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

dlf*_*dlf 1 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)>);
Run Code Online (Sandbox Code Playgroud)

哪里有没有关系Foo,BarBaz.

现在,假设我想将这些寄存器函数中的每一个传递给一个忽略其参数的相同lambda .有什么我可以放在lambda的参数列表中,这意味着"在这里匹配任何东西;我只是想把这个东西扔掉"?

auto listener = []( /* what? */ ) { throw UnsupportedOperationException(); };
RegisterListener1( listener );
RegisterListener2( listener );
RegisterListener3( listener );
Run Code Online (Sandbox Code Playgroud)

我可以使用函数模板而不是lambda,并执行以下操作:

template<typename T>
void listener(T)
{
   throw UnsupportedOperationException();
}

// ...

RegisterListener1( listener<Foo> );
RegisterListener2( listener<Bar> );
RegisterListener3( listener<Baz> );
Run Code Online (Sandbox Code Playgroud)

但这很乏味,特别是如果三个Register函数的仿函数参数都是模板化的,那么就没有简单的方法可以写出"内部"参数类型.这是我在打字过程中遇到的另一个想法:

struct Anything
{
    template<typename T> Anything(const T&) {}
};

// ...

auto listener = [](Anything) { throw UnsupportedOperationException(); }; 
RegisterListener1( listener );
RegisterListener2( listener );
RegisterListener3( listener );
Run Code Online (Sandbox Code Playgroud)

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

Yak*_*ont 5

在C++ 14中,你可以[](auto&&){ throw UnsupportedOperationException(); }.

在C++ 03中,您可以:

struct ignore_and_throw {
  template<class T>
  void operator()(T const&) const {
    throw UnsupportedOperationException();
  }
};
Run Code Online (Sandbox Code Playgroud)

ignore_and_throw()作为你的听众传递 此函数对象具有template operator()您无需指定参数的参数,从而节省了烦人的类型名称重新类型.(ignore_and_throw非常类似于C++ 14 lambda产生的结果).

Anything应该被称为sink_and_ignore或者ignore_arg是可以接受的.