我想创建一个这样的函数:
template < typename Other, typename Func, typename T, typename ...Rest >
void visit( Other &&other, Func &&visitor )
{
// Wrap "visitor" and "other" with "std::forward" calls
visitor( make_object<T>(other) );
visit<Other, Func, Rest...>( other, visitor );
}
问题是"Func"可能不支持列表中的所有类型,那么编译器会在第一个错误的类型上胡说八道。 我不想这样;我希望它执行一些默认操作(就我而言,什么都不做)。
template < typename Other, typename Func, typename T, typename ...Rest >
void visit( Other &&other, Func &&visitor )
{
// Wrap "visitor" and "other" with "std::forward" calls
if ( Func-can-support-T-either-directly-or-by-converting-it )
visitor( make_object<T>(other) );
else
; // might be a throw or a logging instead
visit<Other, Func, Rest...>( other, visitor );
}
我想我可以制作 2 个重载的辅助函数,一个根据兼容性测试获取std::true_type
,另一个std::false_type
. 但是如何创建测试呢?
(感谢有关更好标题和/或其他标签的建议。
与计算中的所有问题一样,您只需要一个简单的间接级别:)
这是一个简单的apply
函数,当事情没有按您希望的那样工作时,它具有默认实现。
template <typename Func>
void apply(Func&& f, ...) { std::cout << "defaultn"; }
template <typename Func, typename T>
auto apply(Func&& f, T&& t) -> decltype(f(std::forward<T>(t))) {
return f(std::forward<T>(t));
}
我们可以很容易地行使它:
struct Foo {};
struct Bar {};
struct F {
void operator()(Foo) { std::cout << "Foon"; }
void operator()(Bar) { std::cout << "Barn"; }
};
int main() {
F f;
Foo foo;
Bar bar;
int i;
apply(f, foo);
apply(f, bar);
apply(f, i);
}
Ideone 给出以下输出:
Foo
Bar
default
不出所料。