c++ - 为什么在直接初始化和赋值中传递 lambda 而不是复制初始化时会编译?

标签 c++ c++11 lambda initialization variable-assignment

为什么赋值运算符不允许在声明对象的同一行中使用 lambda 表达式?

它似乎在 MSVC 中工作。

测试代码: https://godbolt.org/g/n2Tih1

class Func
{
    typedef void(*func_type)();
    func_type m_f;
public:
    Func() {}
    Func(func_type f) : m_f(f) {}
    Func operator=(func_type f) {
        m_f = f;
        return *this;
    }
};

int main()
{
    // doesn't compile in GCC and clang, it does in MSVC
    Func f1 = []() {

    };

    // compiles!
    Func f2;
    f2 = []() {

    };

    // compiles!
    Func f3([]() {

    });
}

最佳答案

Func f1 = []() {};copy initialization ,这需要两个用户定义的隐式转换来构造f1,第一个是从lambda到函数指针,第二个是从函数指针到Func。一个conversion sequence中只允许一个用户定义的隐式转换所以它失败了。

(强调我的)

If T is a class type, and the cv-unqualified version of the type of other is not T or derived from T, or if T is non-class type, but the type of other is a class type, user-defined conversion sequences that can convert from the type of other to T (or to a type derived from T if T is a class type and a conversion function is available) are examined and the best one is selected through overload resolution.

Implicit conversion sequence consists of the following, in this order:

1) zero or one standard conversion sequence;
2) zero or one user-defined conversion;
3) zero or one standard conversion sequence.

对于 f2 = []() {}; 尝试调用适当的赋值运算符,Func 有一个并且它期望函数指针作为参数;只需一次从 lambda 到函数指针的隐式转换,就可以正常工作。

Func f3([]() {});direct initialization ,尝试调用适当的构造函数,Func 有一个,它期望函数指针作为参数。那么就和f2一样。

你可以从拷贝初始化和直接初始化的区别中理解。

In addition, the implicit conversion in copy-initialization must produce T directly from the initializer, while, e.g. direct-initialization expects an implicit conversion from the initializer to an argument of T's constructor.

关于c++ - 为什么在直接初始化和赋值中传递 lambda 而不是复制初始化时会编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50878474/

相关文章:

c++ - 断言中的 Lambda

c++ - qDebug() 不打印任何东西

c++ - 为什么编译器中不存在重新链接按钮?

c++ - 如何打印以逗号分隔的元素列表?

c++ - 为什么返回时调用的是拷贝构造函数而不是 move 构造函数?

java - 在 java 中,我如何在 if lambda 条件中声明一个变量?

c++ - 任何不将大型开关 block 转换为二叉树的编译器?

c++ - 初始化列表: cannot convert ‘Participant’ to ‘unsigned int’ in initialization

c++ - 有没有合理的替代重载和完美转发的方案?

java - 事件处理程序有编译错误 : "local variables referenced from a lambda expression must be final"