Доступ к статическому constexpr std::array без внеклассового определения

У меня есть класс, который определяет некоторые массивы.

Очки.hpp

class Points {

public:

    static constexpr std::array< double, 1 > a1 = { {
            +0.0 } };

    static constexpr std::array< double, 2 > a2 = { {
            -1.0 / std::sqrt( 3.0 ),
            +1.0 / std::sqrt( 3.0 ) } };

};

Затем мой основной файл использует эти массивы.

main.cpp

#include "Points.hpp"

int main()
{
    // Example on how to access a point.
    auto point = Points::a2[0];

    // Do something with point.
}

Когда я компилирую свой код, используя С++ 11 и g++ 4.8.2, я получаю следующую ошибку компоновщика:

undefined reference to `Points::a2'

Я попытался создать файл Points.cpp, чтобы компилятор мог создать из него объектный файл.

Points.cpp

#include "Points.hpp"

Но это не исправило ошибку компоновщика.

У меня сложилось впечатление, что можно инициализировать переменные как статические constexpr в С++ 11 в объявлении класса, а затем обращаться к ним так, как я это делаю, как показано в этом вопросе: https://stackoverflow.com/a/24527701/1991500

Нужно ли мне создавать конструктор для точек, а затем создавать экземпляр класса? Что я делаю неправильно?

Любая обратная связь приветствуется! Спасибо!


person Hernan Villanueva    schedule 21.09.2014    source источник
comment
Вы добавили путь Points.hpp к пути заголовка для компилятора?   -  person texasbruce    schedule 21.09.2014
comment
Points.hpp включен в main.cpp.   -  person Hernan Villanueva    schedule 21.09.2014
comment
Вам необходимо предоставить определение для статических членов данных, если они используются odr.   -  person dyp    schedule 21.09.2014
comment
Что ты имеешь в виду @dyp? Должен ли я не инициализировать их в заголовочном файле?   -  person Hernan Villanueva    schedule 21.09.2014
comment
Это не проблема. Статический элемент данных объявляется только внутри тела класса (declare => имя существует), он определяется вне тела класса (define => связывает объект с именем). Инициализация статических данных-членов в теле класса — странная функция, которая позволяет компилятору использовать значение переменной (во время компиляции) без необходимости запрашивать значение из фактического объекта.   -  person dyp    schedule 21.09.2014
comment
Да, и кстати: sqrt нельзя (переносимо) использовать в контексте, где требуется постоянное выражение. IIRC, это работает только из-за встроенных функций на g++.   -  person dyp    schedule 21.09.2014
comment
Оба g++4.9 и clang++3.5 принимают этот код, если поместить его в один TU и с использованием режима C++14, хотя я не знаю, является ли он переносимым.   -  person dyp    schedule 21.09.2014
comment
Связано: stackoverflow.com/a/23436665   -  person dyp    schedule 21.09.2014


Ответы (1)


Согласно предложению @dyp, я изучил определение статических элементов данных.

Моя проблема требует, чтобы я определил статические переменные-члены моего класса Points.

Следуя примерам в этих вопросах:

Является ли массив constexpr обязательно используемым odr при подписке ?

а также

Определение статических членов в C++

Мне нужно добавить:

// in some .cpp
constexpr std::array< double, 1 > Points::a1;
person Hernan Villanueva    schedule 21.09.2014
comment
Первый поток, на который вы ссылаетесь, говорит о встроенных массивах, поэтому он не имеет отношения к случаю std::array. - person M.M; 11.03.2016