C++11:委托构造函数 - 无法选择构造函数模板?
c++11: delegate constructor - can't select constructor template?
这是一个后续问题:
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");
这不是特定于委派构造函数的。构造函数(和转换函数)没有名称,因此语言中无法向它们提供显式模板参数。引用 C++14, [temp.mem] 14.5.2/5:
注释[ 注意:由于显式模板参数列表跟在函数模板名称之后, 并且因为转换成员函数模板和构造函数成员函数模板被称为 如果不使用函数名称,则无法为这些函数提供显式模板参数列表 函数模板。—尾注 ]
不是规范性的,但这个注释只是明确地阐明了贯穿第14章的规则。
Scott 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);
}
相关文章:
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 将重载的成员函数传递给函数模板
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 具有常量引用参数的函数模板专用化
- std::span<const T> 作为函数模板中的参数
- 如何编写一个完美的缩写函数模板?
- 仅在函数模板中为那些定义了函数的类型执行函数
- 两个函数模板候选项.将一个参数作为引用后,选择不太专业的模板
- 函数模板 - 使用同一类型调用时,使用不同的参数类型选择函数
- C++-14 使用enable_if_t在整型上选择类模板化的成员函数
- 显式函数模板专门化选择了错误的专门化
- 如何选择函数模板专用化
- 如何选择构造函数模板
- 使用模板选择函数的正确版本
- 根据构造函数的可访问性在函数之间进行选择的模板方法
- 为什么编译器选择这个模板函数而不是重载的非模板函数?
- 成员函数模板选择和SFINAE
- C++11:委托构造函数 - 无法选择构造函数模板?
- 根据模板参数选择函数名称