Why can't a static constexpr member variable b

2019-07-11 01:51发布

The following code produces an 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;
}

Why does this code produce the above error and what is the best way to avoid it, considering I want to use the latest version of the standard, C++17?

Should I define the static member variable, just like it was needed in earlier revisions of the standard (see the first answer here: Undefined reference to static constexpr char[]) or should I just create a new Color structure as can be seen below?

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

Edit: I'm using CLion on Ubuntu 16.04, which as far as I could find out, uses g++ 5.4 for compiling. I have set it to use C++17 and still get the same error. The error is only present when color is passed to a function.

2条回答
何必那么认真
2楼-- · 2019-07-11 02:27

The problem was neither with the code itself, nor with the standard being used. CLion's default compiler does not fully support C++17, so that's why it showed a strange behavior that it could compile static constexpr member variables, but only as long as they were not passed to functions.

After updating to the most recent compiler version, I was able to run the code successfully without any changes.

Thank you for all your contribution.

查看更多
地球回转人心会变
3楼-- · 2019-07-11 02:46

This is due to the fact that, before C++17, you had to specifically define the static variable outside the class:

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

const constexpr Color Test::color;

The constexpr-ness of the static member does not let you 'waive' this explicit definition requirement.

With C++17, you no longer need to define static members explicitly. They are implicitly "inline" variables, which get auto-defined at some point, and just once per binary, without you having to take care of it. See here for the long proposal of this feature.

Note that the definition must only appear in a single translation unit (so probably not in a header with class Test that gets included a lot).

查看更多
登录 后发表回答