注意:我使用的是gcc,但在godbolt.org上进行了测试,它也可以在msvc上运行,但不能在clang上运行
我无意中发现,以下简单函数在模板类中编译,但不是作为自由函数编译。有人能解释一下原因吗?
编译OK:
template <typename T = void>
class A
{
public:
static constexpr std::string f()
{
return std::string();
}
}
不编译:
constexpr std::string f()
{
return std::string();
}
抛出错误:
error: invalid return type ‘std::string’ {aka ‘std::__cxx11::basic_string<char>’} of ‘constexpr’ function ...
...
/usr/include/c++/9/bits/basic_string.h:77:11: note: ‘std::__cxx11::basic_string<char>’ is not literal because:
77 | class basic_string
| ^~~~~~~~~~~~
/usr/include/c++/9/bits/basic_string.h:77:11: note: ‘std::__cxx11::basic_string<char>’ has a non-trivial destructor
< code>std::string在C 20中应该是一个文字类型。但是,GCC似乎还没有实现这个新特性,所以它不能接受< code>std::string作为< code>constexpr函数的返回类型。
然而,当< code>constexpr函数是模板的一部分时,它在实例化之前不会作为函数存在。类模板是类的蓝图;它本身不是一个类。当类模板被实例化时,它的成员集就形成了。所以在你的第一个例子中,你所拥有的是一个类模板,它总是产生不良形式的实例化,因为< code>A