lambda中的虚拟参数将匹配任何类型?

时间:2014-09-25 14:49:52

标签: c++ lambda

假设我有这样的事情:

struct Foo {};
struct Bar {};
struct Baz {};

// ...

void RegisterListener1(std::function<void(Foo)>);
void RegisterListener2(std::function<void(Bar)>);
void RegisterListener3(std::function<void(Baz)>);

FooBarBaz之间没有任何关系。

现在,假设我想将这些寄存器函数中的每一个传递给忽略其参数的相同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 );

我实际上对此很好,也许我不再需要问这个问题了,但还有更好的选择吗?

1 个答案:

答案 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_ignoreignore_arg,并且可以接受。