5

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.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
TonyK
  • 16,761
  • 4
  • 37
  • 72
  • https://stackoverflow.com/questions/53630837/is-this-a-bug-constexpr-constructor-silently-becomes-non-constexpr https://stackoverflow.com/questions/58866631/constexpr-member-function Note the "no diagnostic required" part. – KamilCuk Dec 08 '20 at 16:34
  • Does this answer your question? [Is this a bug? Constexpr constructor silently becomes non-constexpr](https://stackoverflow.com/questions/53630837/is-this-a-bug-constexpr-constructor-silently-becomes-non-constexpr) – idmean Dec 08 '20 at 16:36
  • 2
    @idmean: I think template makes just it No diagnostic Required (NDR). – Jarod42 Dec 08 '20 at 16:37
  • https://stackoverflow.com/questions/26568820/why-do-templates-allow-constexpr-function-members-with-non-constexpr-constructor looks similar, just uses `std::array` instead of `C`. – KamilCuk Dec 08 '20 at 16:40
  • 1
    @KamilCuk: Whoa, so the code is invalid, but no diagnostic is required? OK -- but is it _safe_? I'm guessing not. – TonyK Dec 08 '20 at 16:43

0 Answers0