Does a literal class with std :: string work only with a template?

The following definition is not allowed by my compiler, since std::string has a nontrivial destructor (it makes sense that teststr cannot have a trivial dtor if the member does not):

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

However, the following equivalent (to my knowledge) definition of 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; 

What is a template for a template that resolves this definition?

+5
source share
1 answer

constexpr most often allowed in templates, because at the time of template definition it is not known at all whether the element satisfies constexpr requirements. When a constexpr template member is constexpr , it is determined during the instantiation of the template whether constexpr suitable, and if not, it is silently discarded.

Considering

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

you may have

 constexpr test<int> i = 3; 

since with T = int constructor satisfies the requirements of constexpr , but you cannot have

 constexpr test<string> s = ""; 

because this constructor does not meet the requirements of constexpr .

It is not difficult to create an instance of test<string> , because this will greatly limit the possibility of using constexpr in templates.

From the standard (C ++ 11):

7.1.5 constexpr specifier [dcl.constexpr]

6 If the specialized specialization of the constexpr function constexpr or member function of the class template does not satisfy the requirements for the constexpr function or constexpr constructor, this specialization is not a constexpr or constexpr . [...]

+5
source

Source: https://habr.com/ru/post/1210009/


All Articles