为什么这个算符(“lambda”)会发出奇怪的警告?

时间:2011-08-25 05:20:48

标签: c++ templates visual-c++ anonymous-types functor

当我使用Visual C ++ 2010编译并运行它时:

#include <iostream>

int main() {
    int subtrahend = 5;

    struct Subtractor {
        int &subtrahend;
        int operator()(int minuend) { return minuend - subtrahend; }
    } subtractor5 = { subtrahend };

    std::cout << subtractor5(47);
}

我得到了正确答案,42。

然而,编译器抱怨这是不可能的:

  

Temp.cpp(9):警告C4510:main::Subtractor:无法生成默认构造函数
  Temp.cpp(6):参见 main::Subtractor

的声明      

Temp.cpp(9):警告C4512:main::Subtractor:无法生成赋值运算符
  Temp.cpp(6):参见 main::Subtractor

的声明      

Temp.cpp(9):警告C4610:struct main::Subtractor 永远无法实例化 - 需要用户定义的构造函数

发生了什么事?

4 个答案:

答案 0 :(得分:4)

前两个警告只是让你知道由于存在引用数据成员而无法生成隐式声明的成员函数。

第三个警告是a Visual C++ compiler bug

所有三个警告都可以被忽略,没有任何不良影响,尽管你可以通过使参考数据成员成为一个指针来轻松地使所有三个警告消失(参考数据成员几乎不值得麻烦)。

答案 1 :(得分:1)

第一个警告是告诉您不能默认构造引用值(保证引用指向某个值)。将减数切换为常规整数,问题就会消失。

我很确定第二次警告性质相似。

(只是说,依靠boost :: function或类似的实现(std :: tr1 :: function?)而不是手动编写这段代码通常要好得多)

答案 2 :(得分:0)

这是因为变量subtractor5是一个未命名的结构。如果你想让错误消失,请给subtractor5使用的结构命名。

例如:

struct subtractor {
 :
} subtractor5 = { subtrahend };

遗憾的是,我不知道足够的C ++语言,知道它为什么会起作用,但我知道为什么会发生警告。

答案 3 :(得分:0)

在以下情况下,用户定义的构造函数是必需的:

  • 初始化常量数据成员(const int c_member;)。
  • 初始化参考数据成员(int & r_member;
  • 拥有类型没有默认构造函数的数据成员。例如:

    班级NoDefCtor { 上市:    NoDefCtor(INT); };

    类包含那个 {    NoDefCtor no_ctor_member; };

  • 继承基类,其中基类没有默认构造函数。与上面几乎相同(NoDefCtor)。