Why can't a static constexpr member variable be passed to a function?

3883 views c++
3

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});

answered question

What's your compiler? That's a compiler bug if you did indeed compile your code with C++17.

I got the same error when I compiled with --std=c++14, but it worked fine with --std=c++17. I'm using gcc.

I'm using CLion with the default compiler on Ubuntu 16.04. I set the appropriate flag in my CMakeLists.txt : set(CMAKE_CXX_STANDARD 17)

1 Answer

1

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 explicily. 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).

posted this

Have an answer?

JD

Please login first before posting an answer.