Функция 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но это не помогло.

0 ответов

Другие вопросы по тегам