LINUX.ORG.RU

constexpr массивы в c++

 


0

2

Вот простой пример:

#include <iostream>

class A
{
 static constexpr int a[]={0,1,2,3,4};
 public:
 static int Get(size_t ind) { return a[ind]; }
};

int main(int argc, char** argv)
{
 std::cout<<A::Get(argc)<<std::endl;
 return 0;
}
Собираю с g++. Получаю ошибку компоновщика
function A::Get(unsigned long): error: undefined reference to 'A::a'
Понятно, что компилятор делает constexpr массив не constexpr, но какого хрена и почему компоновщик его не находит? Тем более, что, если массив не в составе класса, то всё работает:
#include <iostream>

constexpr int a[]={0,1,2,3,4};
int Get(size_t ind) { return a[ind]; }

int main(int argc, char** argv)
{
 std::cout<<Get(argc)<<std::endl;
 return 0;
}
Пробовал с clang++, результаты идентичные.


компилятор делает constexpr массив не constexpr

С чего это?

xDShot ★★★★★ ()
#include <iostream>

class A
{
 static constexpr int a[]={0,1,2,3,4};
 public:
 static int Get(size_t ind) { return a[ind]; }
};

constexpr int A::a[];

int main(int argc, char** argv)
{
 std::cout<<A::Get(argc)<<std::endl;
 return 0;
}

Определять static член класса надо независимо от того, constexpr оно или нет, ЕМНИП.

Makhno ()

cppreference:

Definitions are declarations that fully define the entity introduced by the declaration. Every declaration is a definition, except for the following: ... Namespace scope declaration of a static data member that was defined within the class with the constexpr specifier

https://en.cppreference.com/w/cpp/language/definition

Makhno ()

В С++ похоже нашли еще один способ трахнуть мозг разработчика. Как-то раньше жили без этих constexpr. Серьезно: зачем это нужно? Если не написать constexpr, то все будет работать куда хуже?

hotpil ★★★ ()
Ответ на: комментарий от Makhno

Вариант рабочий, да. Но

#include <iostream>

class A
{
 static constexpr int a[]={0,1,2,3,4};
 static constexpr size_t sz=sizeof(a);
 public:
 static size_t Sz() { return sz; }
};

int main(int argc, char** argv)
{
 std::cout<<A::Sz()<<std::endl;
 return 0;
}
работает и без внешнего определения sz (и a, но это понятно).

JaM ()
Ответ на: комментарий от JaM

С каким стандартом собираешь, к слову? Если С++17, то там эту лажу с ODR на static constexpr вроде как отменили.

Makhno ()
Ответ на: комментарий от hotpil

Ну типа новый стандарт, вот не окрепшие умы и начинают лепить фитчи из него направо и налево, надо это или нет - неважно. Главное использовать. У меня другого объяснения нет. Как говориться чем бы дите не тешилось, лишь бы не плакало.

B00 ()

constexpr малополезна, пока нельзя будет заставить компилятор вычислять constexpr фунции на этапе компиляции (или свалиться с ошибкой, если это невозможно). Или я не прав?

Crocodoom ★★★ ()
Ответ на: комментарий от Crocodoom

constexpr малополезна, пока нельзя будет заставить компилятор вычислять constexpr фунции на этапе компиляции (или свалиться с ошибкой, если это невозможно)

Если результат сохраняется в constexpr переменную, а функция не может вычислить результат при компиляции - будет ошибка.

anonymous ()

но какого хрена и почему компоновщик его не находит?

Ты вообще static до этого использовал? constexpr тут не причем. Ну и в данном случае тебе нужен static inline.

anonymous ()
Ответ на: комментарий от anonymous

Ну понятно. В принципе да, локальную проверку можно сделать так, как ты сказал, а глобальная и не нужна

Crocodoom ★★★ ()
Ответ на: комментарий от hotpil

С++ пошёл тернистым путём греха, когда там появились шаблоны. Штука сатанинская, ибо затягивает, порой в ущерб собственно программированию. constexpr - это, так сказать, побочный эффект.

JaM ()
Ответ на: комментарий от anonymous

Для тех, кто в танке. Это минимизированный тестовый код на базе реального, где и всплыла эта проблема. И уж inline для функций, определённых в теле класса, мне точно не нужен.

JaM ()
Ответ на: комментарий от Makhno

Makhno, спасибо! C -std=с++17 действительно работает. Пока воспользуюсь твоим первым советом с вынесенными объявлениеми, а буду переходить на c++17 выкину их.

JaM ()
Ответ на: комментарий от hotpil

В С++ похоже нашли еще один способ трахнуть мозг разработчика. Как-то раньше жили без этих constexpr.

Да вообще, напримумывали этих компутеров, раньше как-то счётами считали и ничего.

Серьезно: зачем это нужно? Если не написать constexpr, то все будет работать куда хуже?

Документация вдруг исчезла из интернета?

slovazap ★★★★★ ()
Ответ на: комментарий от hotpil

Кто пустил ребёнка в лабораторию к серьёзным дядям?

anonymous ()
Ответ на: комментарий от Makhno

Если С++17, то там эту лажу с ODR на static constexpr вроде как отменили.

Аллилуйя!

Stil ★★★★★ ()
Ответ на: комментарий от hotpil

В С++ похоже нашли еще один способ трахнуть мозг разработчика.

Тебе-то повезло, тебя некуда трахать.

Как-то раньше жили без этих constexpr. Серьезно: зачем это нужно? Если не написать constexpr, то все будет работать куда хуже?

Дело тут вообще не в constexpr.

anonymous ()
Ответ на: комментарий от Makhno

А что конкретно поменяли в стандарте?

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.