假设我有这样的事情:
struct Foo {};
struct Bar {};
struct Baz {};
// ...
void RegisterListener1(std::function<void(Foo)>);
void RegisterListener2(std::function<void(Bar)>);
void RegisterListener3(std::function<void(Baz)>);
Foo
,Bar
和Baz
之间没有任何关系。
现在,假设我想将这些寄存器函数中的每一个传递给忽略其参数的相同lambda 。我可以在lambda的参数列表中添加任何内容,这意味着&#34;匹配任何内容;无论如何,我只是想扔掉东西&#34;?
auto listener = []( /* what? */ ) { throw UnsupportedOperationException(); };
RegisterListener1( listener );
RegisterListener2( listener );
RegisterListener3( listener );
我可以使用函数模板而不是lambda,并执行以下操作:
template<typename T>
void listener(T)
{
throw UnsupportedOperationException();
}
// ...
RegisterListener1( listener<Foo> );
RegisterListener2( listener<Bar> );
RegisterListener3( listener<Baz> );
但这很乏味,特别是如果三个Register函数的仿函数参数都是模板化的,那么就没有简单的方法可以写出&#34; inner&#34;参数类型。这是我在打字过程中遇到的另一个想法:
struct Anything
{
template<typename T> Anything(const T&) {}
};
// ...
auto listener = [](Anything) { throw UnsupportedOperationException(); };
RegisterListener1( listener );
RegisterListener2( listener );
RegisterListener3( listener );
我实际上对此很好,也许我不再需要问这个问题了,但还有更好的选择吗?
答案 0 :(得分:5)
在C ++ 14中,您可以[](auto&&){ throw UnsupportedOperationException(); }
。
在C ++ 03中,你可以:
struct ignore_and_throw {
template<class T>
void operator()(T const&) const {
throw UnsupportedOperationException();
}
};
并传递ignore_and_throw()
作为您的听众。此函数对象具有template
operator()
,您无需指定参数,从而为您节省烦人的类型名称重新类型。 (ignore_and_throw
与C ++ 14 lambda产生的非常类似。)
您的Anything
可能应该被称为sink_and_ignore
或ignore_arg
,并且可以接受。