Sit*_*myu 9 c++ lambda class c++11 std-function
TestCase2并且TestCase3可以正常编译。但是,TestCase1我收到以下错误:
E0312, Custom conversion from "lambda []void ()->void" to
"EventHandler" is not appropriate.
Run Code Online (Sandbox Code Playgroud)
为什么我会收到此错误?我想知道如何解决。
#include <functional>
#include <iostream>
class EventHandler
{
std::function<void()> _func;
public:
int id;
static int counter;
EventHandler() : id{ 0 } {}
EventHandler(const std::function<void()>& func) : _func{ func }
{
id = ++EventHandler::counter;
}
};
int EventHandler::counter = 0;
int main()
{
EventHandler TestCase1 = []() {};
EventHandler TestCase2([]() {});
EventHandler TestCase3 = static_cast<std::function<void()>>([]() {});
}
Run Code Online (Sandbox Code Playgroud)
JeJ*_*eJo 14
为什么我会收到此错误?
lambda[]() {}与 不同std::function<void()>。这意味着
decltype([]() {}) != std::function<void()>
Run Code Online (Sandbox Code Playgroud)
并且必须隐式或显式转换它。
在行
EventHandler TestCase1 = []() {};
Run Code Online (Sandbox Code Playgroud)
进行复制初始化,编译器首先必须将 lambda 转换为 a std::function<void()>,然后转换为EventHandler对象。编译器不能执行双重隐式约定。
因此,你需要在这里明确,就像在TestCase3例子中一样。
我想知道如何解决。
一种方法是提供模板化构造函数(如果您愿意)
#include <type_traits> // std::is_convertible_v
class EventHandler
{
std::function<void()> _func;
public:
template<typename Func> EventHandler(Func func)
: _func{ func }
{
static_assert(std::is_convertible_v<Func, decltype(_func)>
, "is not valid arg!");
// ....
}
// or in C++20 with <concepts> header
// template<typename Func> EventHandler(Func func)
// requires std::convertible_to<Func, decltype(_func)>
// : _func{ func }
// { ... }
};
Run Code Online (Sandbox Code Playgroud)
现在你可以
EventHandler TestCase1 = []() {}; // works
Run Code Online (Sandbox Code Playgroud)