Почему статическая переменная-член constexpr не может быть передана в функцию? - PullRequest
0 голосов
/ 16 сентября 2018

Следующий код выдает 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?

Должен ли я определять статическую переменную-член так же, как это было необходимо в более ранних версиях стандарта (см. Первый ответ здесь: Неопределенная ссылка на статический символ constexpr [] ) или мне просто нужно создать новая Color структура как видно ниже?

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

Edit: Я использую CLion в Ubuntu 16.04, который, насколько я мог узнать, использует g ++ 5.4 для компиляции. Я установил его на использование C ++ 17 и все еще получаю ту же ошибку. Ошибка присутствует только тогда, когда color передается функции.

Ответы [ 2 ]

0 голосов
/ 16 сентября 2018

Проблема была не в самом коде и не в используемом стандарте. Компилятор по умолчанию CLion не полностью поддерживает C ++ 17, поэтому он продемонстрировал странное поведение, заключающееся в том, что он может компилировать static constexpr переменные-члены, но только до тех пор, пока они не были переданы в функции.

После обновления до самой последней версии компилятора я смог успешно выполнить код без каких-либо изменений.

Спасибо за ваш вклад.

0 голосов
/ 16 сентября 2018

Это связано с тем, что до C ++ 17 вам приходилось специально определять статическую переменную вне класса:

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

const constexpr Color Test::color;

Недостаток статического члена не позволяет вам отказаться от этого требования явного определения.

В C ++ 17 вам больше не нужно явно определять статические члены. Они неявно являются «встроенными» переменными, которые автоматически определяются в определенный момент, и только один раз для двоичного файла, без необходимости заботиться об этом. См. здесь для подробного описания этой функции.

Обратите внимание, что определение должно появляться только в одноместной единице перевода (поэтому, вероятно, не в заголовке с классом Test, который часто включается).

...