带有std :: string的Literal类只适用于模板特化?

Mat*_*att 5 c++ templates c++11

我的编译器不允许使用以下定义,因为它std::string有一个非平凡的析构函数(teststr理所当然,当成员没有时,它不能有一个简单的dtor):

class teststr
{
private:
    std::string _m;
public:
    constexpr teststr(std::string value) : _m(value) {};

    constexpr std::string m() const { return _m; }
    void m(std::string value) { _m = value; }
};
Run Code Online (Sandbox Code Playgroud)

但是,teststr允许以下等效(据我所知)定义:

template<typename T>
class test
{
private:
    T _m;
public:
    constexpr test(T value) : _m(value) {};

    constexpr T m() const { return _m; }
    void m(T value) { _m = value; }
};

typedef test<std::string> teststr;
Run Code Online (Sandbox Code Playgroud)

模板允许这个定义的类型是什么?

小智 5

constexpr更常见的是在模板中允许,因为在模板定义时通常不知道成员是否满足要求constexpr.当一个模板成员宣布constexpr,它在模板实例化时确定是否constexpr是合适的,如果不是,则丢弃.

特定

template <typename T> struct test {
  T val;
  constexpr test(T val) : val(val) { }
};
Run Code Online (Sandbox Code Playgroud)

你可以有

constexpr test<int> i = 3;
Run Code Online (Sandbox Code Playgroud)

因为有T = int,构造函数符合要求constexpr,但你不能拥有

constexpr test<string> s = "";
Run Code Online (Sandbox Code Playgroud)

因为那个构造函数不符合要求constexpr.

实例化并不是一个很难的错误,test<string>因为这会严重限制constexpr在模板中使用的能力.

从标准(C++ 11):

7.1.5 constexpr说明符[dcl.constexpr]

6如果一个的被实例化的模板特constexpr类模板的功能模板或成员函数将不能满足一个要求constexpr的功能或constexpr构造,即专业化不是constexpr功能或constexpr构造.[...]