Является ли следующий код правильным использованием функций constexpr
? По сути, он пытается получить доступ к переменной static constexpr
_size
различными способами.
Компилируется без проблем, используя g++
, но завершается неудачно с msvc-2017 / 2019
и clang
.
. Пример кода, доступный для тестирования через godbolt здесь .
Кажется, что это можно сделать для компиляции (везде), если функция constexpr
заменена эквивалентным макрообработкой , Раскомментируйте USE_MACRO_WORKAROUND
для проверки.
Мне кажется, это наводит на мысль об ошибке компилятора, связанной с constexpr
функциями?
(Поскольку макро-версия работает, это предполагает, что у компилятора должно быть достаточно информации времени компиляции, чтобы иметь дело с функцией constexpr
. Очевидно, g++
может сделать это ...)
(Этот пример - просто выдумка. Настоящий код является частью этой библиотеки ).
#include <cstddef>
//define USE_MACRO_WORKAROUND
template <size_t N = +1>
struct expansion
{
size_t static constexpr _size = N ;
double _xdat [ N ] ;
};
#if defined(USE_MACRO_WORKAROUND)
// ugly macro-based hack that's equiv. to compile
// time foo()...
// does compile everywhere
#define foo(_aa, _bb) _aa._size + _bb._size
#else
// why does this cause problems? works for g++ 7,
// 8, 9, but not msvc, etc
template <size_t NA, size_t NB>
inline size_t constexpr foo (
expansion <NA> const& _aa,
expansion <NB> const& _bb
)
{
return _aa._size + _bb._size;
}
#endif //USE_MACRO_WORKAROUND
template <size_t NA, size_t NB>
inline void goo (
expansion <NA> const& _xx,
expansion <NB> const& _yy
)
{ // this will not compile with msvc, reporting
// C2131: expression did not evaluate to a constant
expansion<foo(_xx, _yy)> _tt;
}
int main ()
{
expansion< 2 > _x2;
expansion< 4 > _x4;
// this seems to work for both g++ and msvc
expansion<foo(_x2, _x4)> _x6;
// via msvc, this leads to the errors above
goo (_x2, _x4) ;
return 0;
}