2016-07-13 120 views
4

这是一个后续问题:
c++11 dedicated "proxy constructors" delegating to private univeral reference constructor?C++ 11:委托构造函数 - 不能选择构造函数模板?

我想摆脱掉那里使用的“枚举类假人”。

但我没有设法委托给模板构造函数。
请参阅下面的代码示例。

#include <iostream> 
#include <string> 
#include <typeinfo> 

class MyClass 
{ 

private: 

    template <class T> 
    MyClass(T&& data) 
    : _data(std::forward<T>(data)) 
    { 
     std::cout << "MyClass universal reference template c'tor" << std::endl; 
    } 

public: 


    // proxy c'tors delegating to universal reference c'tor 
    MyClass (std::string const & data) 
    : MyClass<std::string>(data) 
    { 
     std::cout << "MyClass lvalue c'tor" << std::endl; 
    } 

    MyClass (std::string && data) 
    : MyClass<std::string>(std::move(data)) 
    { 
     std::cout << "MyClass rvalue c'tor" << std::endl; 
    } 

private: 

    std::string _data; 

}; 

int 
main(
     int, 
     char**) 
{ 

    { 
     std::string str("demo"); 
     MyClass myClass(str); 
    } 

    { 
     MyClass myClass("hello, world"); 
    } 

    return 0; 
} 

我获得以下错误:

main2.cpp: In constructor 'MyClass::MyClass(const string&)': 
main2.cpp:21:7: error: 'class MyClass MyClass::MyClass' is not a non-static data member of 'MyClass' 
: MyClass<std::string>(data) 
^
main2.cpp:21:14: error: expected '(' before '<' token 
: MyClass<std::string>(data) 
     ^
main2.cpp:21:14: error: expected '{' before '<' token 
main2.cpp: In constructor 'MyClass::MyClass(std::__cxx11::string&&)': 
main2.cpp:27:7: error: 'class MyClass MyClass::MyClass' is not a non-static data member of 'MyClass' 
: MyClass<std::string>(std::move(data)) 
^
main2.cpp:27:14: error: expected '(' before '<' token 
: MyClass<std::string>(std::move(data)) 
     ^
main2.cpp:27:14: error: expected '{' before '<' token 
main2.cpp: In function 'int main(int, char**)': 
main2.cpp:11:5: error: 'MyClass::MyClass(T&&) [with T = std::__cxx11::basic_string<char>&]' is private 
MyClass(T&& data) 
^ 
main2.cpp:46:28: error: within this context 
    MyClass myClass(str); 
         ^
main2.cpp:11:5: error: 'MyClass::MyClass(T&&) [with T = const char (&)[13]]' is private 
MyClass(T&& data) 
^ 
main2.cpp:50:39: error: within this context 
    MyClass myClass("hello, world"); 

回答

4

这是不特定于委托构造函数。构造函数(和转换函数)没有名称,因此在语言中没有办法向它们提供显式模板参数。引用C++ 14,[temp.mem] 14.5.2/5:

[ Note: Because the explicit template argument list follows the function template name, and because conversion member function templates and constructor member function templates are called without using a function name, there is no way to provide an explicit template argument list for these function templates. —end note ]

说明不规范,但本说明只是明确地阐明了从规则贯穿章接下来14

2

斯科特Mayers毫无疑问是一名C++专家,但他并不总是对的。

问题:

允许尽可能高效率地建设,限制副本如有可能

答:

的X值构造,通过的std :: enable_if限制:

#include <iostream> 
#include <string> 
#include <type_traits> 

class MyClass 
{ 

public: 

    template <class T, std::enable_if_t<std::is_constructible<std::string, T>::value>* = nullptr> 
    MyClass(T&& data) 
    : _data(std::forward<T>(data)) 
    { 
     std::cout << "MyClass universal reference template c'tor" << std::endl; 
    } 

private: 

    std::string _data; 

}; 

int main() 
{ 
    using namespace std::string_literals; 

    auto a = MyClass("hello"s); 
    auto b = MyClass("world"); 


    const auto s = "Hello, World"s; 
    auto s2 = "Hello, World"; 

    auto c = MyClass(s); 
    auto d = MyClass(s2); 

// won't compile 
// auto e = MyClass(10); 

} 
+0

我的错:Scott Meyer正在处理第27条 –

+0

中的问题,那并不完全如此。但是对于类似的情况,使用SFINAE进行模板元编程。你的榜样帮助我更好地理解 - 非常感谢! –