constexpr 函数仅在声明为看似无关的模板时才有效

Ton*_*nyK 5 c++ function-templates c++17 constexpr-function

以下代码无法编译;g++ 7.3.0 with--std=c++17给出了错误信息

constexpr 函数 'constexpr const C operator+(const C&, int)' 的无效返回类型 'const C'
注意:'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()) ;
  }
Run Code Online (Sandbox Code Playgroud)

好吧,好吧。但是如果我添加一个看似无关的模板规范到operator+

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

然后它编译并运行,C T按预期打印。

这里发生了什么?如果非平凡的析构函数是编译第一个的障碍,那么当存在相同的障碍时,它如何愉快地编译第二个呢?有没有一个很好的方法来解决这个问题(即一个不使用template黑客的方法)?我试过了,inline但没有帮助。