Jon*_*Mee 3 c++ methods lambda templates metaprogramming
所以出于示例的目的,假设我有3个简单的structs,其中第二个不包含bar方法:
struct one {
void foo(const int);
void bar();
};
struct two {
void foo(const int);
};
struct three {
void foo(const int);
void bar();
};
Run Code Online (Sandbox Code Playgroud)
然后我有一个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(); } ); }
};
Run Code Online (Sandbox Code Playgroud)
当我尝试编译这个时,我得到:
错误:
struct two没有成员命名bar
有没有办法可以解决这个问题?
T.C*_*.C. 11
首先,公用事业.一个是我们最喜欢的overload,展示了三个C++ 17特性,并且重载了operator()几个函数对象,全部分为两行.
template<class... Ts> struct overload : Ts... { using Ts::operator()...; };
template<class... Ts> overload(Ts...) -> overload<Ts...>;
Run Code Online (Sandbox Code Playgroud)
然后是accept-everything回退标记类型:
struct fallback_t { template<class T> fallback_t(T&&) {} };
Run Code Online (Sandbox Code Playgroud)
现在来电话本身.我们通过将value.bar()调用放入尾随返回类型来使原始泛型lambda SFINAE友好,然后使用具有未定义行为的回退重载来重载它(如果实际调用的话)(因为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(); }
} );
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
133 次 |
| 最近记录: |