字面量类只能用于 std::string 的模板特化吗?

5

下面这个定义在我的编译器中不被允许,因为std::string有一个非平凡的析构函数(当成员变量存在时,teststr无法拥有平凡的析构函数是有意义的):

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; }
};

然而,根据我所知,以下等效的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;

什么是模板类型定义的允许条件?

也许可以提供你正在使用的编译器? - Creris
g++(rev5,由MinGW-W64项目构建)4.8.1 - Matt
1
当您实例化typedef时会发生什么? - Captain Giraffe
1
http://en.cppreference.com/w/cpp/language/constexpr提到非模板构造函数的要求:“当提供适当的参数时,非模板、非默认的constexpr函数或非模板、非默认、非继承的constexpr构造函数必须产生核心常量表达式。”因此,我猜类模板的构造函数可能会有所不同(`T`可以是满足constexpr要求的类型)。 - mip
是的,使用“int”而不是“std :: string”也可以成功。http://ideone.com/Xd2qr6 - mip
显示剩余4条评论
1个回答

5

constexpr在模板中更常被允许,因为在模板定义时通常不知道成员是否符合constexpr的要求。当一个模板成员被声明为constexpr时,会在模板实例化时确定是否适用constexpr,如果不适用,则会被静默丢弃。

给定:

template <typename T> struct test {
  T val;
  constexpr test(T val) : val(val) { }
};

你可以拥有
constexpr test<int> i = 3;

因为使用 T = int,构造函数符合constexpr的要求,但您不能这样做。
constexpr test<string> s = "";

因为那个构造函数不符合constexpr的要求,所以无法实例化test<string>是不会产生严重限制模板中使用constexpr的错误。

从标准(C++11)中可以了解到:

7.1.5 constexpr说明符 [dcl.constexpr]

6 如果一个constexpr函数模板或类模板的成员函数的实例化模板特化不能满足constexpr函数或constexpr构造函数的要求,则该特化不是constexpr函数或constexpr构造函数。[...]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接