因此,出于示例的目的,假设我有 3 个简单的struct
是,其中第二个不包含bar
method:
struct one {
void foo(const int);
void bar();
};
struct two {
void foo(const int);
};
struct three {
void foo(const int);
void bar();
};
然后我有一个struct
它将管理这些类型的对象:
struct owner {
map<int, one> ones;
map<int, two> twos;
map<int, three> threes;
template <typename T, typename Func>
void callFunc(T& param, const Func& func) {
func(param);
}
template <typename T>
void findObject(int key, const T& func) {
if(ones.count(key) != 0U) {
callFunc(ones[key], func);
} else if(twos.count(key) != 0U) {
callFunc(twos[key], func);
} else {
callFunc(threes[key], func);
}
}
void foo(const int key, const int param) { findObject(key, [&](auto& value) { value.foo(param); } ); }
void bar(const int key) { findObject(key, [&](auto& value) { value.bar(); } ); }
};
当我尝试编译这个时,我得到:
error: struct two
没有指定成员bar
有什么办法可以解决这个问题吗?
Live Example
首先,公用事业。其中一个是我们最喜欢的overload
展示了三个 C++17 功能,并重载了operator()
几个函数对象,全部在两行中。
template<class... Ts> struct overload : Ts... { using Ts::operator()...; };
template<class... Ts> overload(Ts...) -> overload<Ts...>;
然后是 Accept-Everything 后备标签类型:
struct fallback_t { template<class T> fallback_t(T&&) {} };
现在来看看通话本身。我们通过将原始通用 lambda SFINAE 放入value.bar()
调用尾随返回类型,然后使用后备重载对其进行重载,如果实际调用,该后备重载具有未定义的行为(因为OP“省略[ted]任何显式行为定义”):
void bar(const int key) {
findObject(key, overload {
[&](auto& value) -> decltype(void(value.bar())) { value.bar(); },
[](fallback_t){ fire_missiles_and_impregnate_cat(); }
} );
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)