为什么不能将静态constexpr成员变量传递给函数?

时间:2018-09-16 14:44:54

标签: c++ inline c++17 constexpr static-members

以下代码产生一个undefined reference to 'Test::color'

#include <iostream>

struct Color{
    int r,g,b;
};

void printColor(Color color) {
    //printing color
}

class Test {
    static constexpr Color color = {242,34,4};
public:
    void print(){
        printColor(color);
    }
};


int main() {
    Test test;
    test.print();

    return 0;
}

考虑到我想使用标准的最新版本C ++ 17,为什么此代码会产生上述错误,以及避免该错误的最佳方法是什么?

我应该定义静态成员变量,就像在标准的早期版本中需要的那样(请参见此处的第一个答案:Undefined reference to static constexpr char[]),还是应该像创建新的Color结构一样在下面看到?

printColor(Color{color.r, color.g, color.b});

编辑: 我在Ubuntu 16.04上使用CLion,据我所知,它使用g ++ 5.4进行编译。我已将其设置为使用C ++ 17,但仍然收到相同的错误。仅将color传递给函数时,才会出现该错误。

2 个答案:

答案 0 :(得分:3)

这是由于以下事实:在C ++ 17之前,您必须在类之外专门定义静态变量:

class Test { 
   /* ... etc etc ... */
}

const constexpr Color Test::color;

静态成员的可解释性不允许您“放弃”这种明确的定义要求。

使用C ++ 17,您不再需要显式定义静态成员。它们是隐式的“内联”变量,该变量在某个时候会自动定义,每个二进制文件仅定义一次,而无需您理会。有关此功能的详细建议,请参见here

请注意,定义只能出现在单个转换单元中(因此可能不会出现在包含很多Test的类的标头中)。

答案 1 :(得分:0)

问题既不在于代码本身,也不在于所使用的标准。 CLion的默认编译器不完全支持C ++ 17,因此它表现出奇怪的行为,它可以编译static constexpr成员变量,但前提是只要不将其传递给函数即可。

更新到最新的编译器版本后,我能够成功运行代码,而无需进行任何更改。

感谢您的所有贡献。