Функция constexpr работает только в том случае, если она объявлена как кажущийся нерелевантным шаблон.
Следующий код не компилируется; г++ 7.3.0 с
--std=c++17
выдает сообщение об ошибке
недопустимый возвращаемый тип 'const C' функции constexpr 'constexpr const C operator+(const C&, int)'
примечание: 'C' не является литералом, поскольку 'C' имеет нетривиальный деструктор
#include <string>
using namespace std ;
struct C
{
C (std::string s) : s (s) { }
std::string s ;
} ;
constexpr const C operator+ (const C& x, int y) // <-- Error here
{
return C ("C int") ;
}
int main()
{
C c ("abc") ;
printf ("%s\n", (c + 99).s.c_str()) ;
}
Ладно, хорошо. Но если я добавлю, казалось бы, нерелевантную спецификацию шаблона в
operator+
:
template<typename T>
constexpr const C operator+ (const C& x, T y)
{
return C ("C T") ;
}
затем он компилируется и запускается, печатая
C T
как и ожидалось.
Что тут происходит? Если нетривиальный деструктор является препятствием для компиляции первого, как он может благополучно скомпилировать второй, когда такой же барьер существует? И есть ли хороший способ обойти это (т.е. тот, который не использует
template
взломать)? Я старался
inline
но это не помогло.