constexpr function only works if declared as a seemingly irrelevant template

97 views Asked by At

The following code doesn't compile; g++ 7.3.0 with --std=c++17 gives the error message

invalid return type 'const C' of constexpr function 'constexpr const C operator+(const C&, int)'
note: 'C' is not literal because 'C' has a non-trivial destructor

#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()) ;
  }

Well, OK. But if I add a seemingly irrelevant template specification to operator+:

template<typename T>
constexpr const C operator+ (const C& x, T y)
  {
  return C ("C T") ;
  }

then it compiles and runs, printing C T as expected.

What's going on here? If the non-trivial destructor is a barrier to compiling the first one, how can it happily compile the second one, when the same barrier exists? And is there a nice way around this (i.e. one that doesn't use the template hack)? I tried inline but it didn't help.

0

There are 0 answers