在构造函数中C++自动类型推断
C++ automatic type deduction in constructor
我正在尝试理解我今天看到的以下代码。我已经尝试找到一个相关的问题,但由于我不知道C++的这个功能叫什么,所以很难找到相关的帖子。关于正确搜索词的提示可能已经对我有所帮助。
struct A
{ int x; };
struct B
{ B(A a) {}; };
int main()
{
B b{ { 5 } }; // works, seems to create a struct A from {5} and pass it to B's constructor
std::make_unique<B>({ 5 }); // doesn't compile
return 0;
}
为什么{5}
传递给make_unique
时不用于创建结构 A,而是在B
的构造函数中以这种方式使用?
如果 B 有第二个构造函数B(int foo) {};
那么将使用这个构造函数而不是上面的一个 frome(至少这是我通过反复试验发现的)。决定参数是自动用于创建struct A
还是直接用作构造函数中的int
的规则是什么?
我正在使用Visual C++ 14.0
下面是一个简化的演示:
struct X { X(int); };
void foo(X );
template <typename T> void bar(T );
foo({0}); // ok
bar({0}); // error
问题是大括号初始化列表s,那些只是浮动{...}
s的结构,在C++是奇怪的野兽。它们没有类型 - 它们的意思必须从它们的实际使用方式中推断出来。当我们调用foo({0})
时,大括号的初始化列表用于构造一个X
因为这是参数 - 它的行为就像我们写X{0}
一样。
但是在bar({0})
,我们没有足够的上下文来知道如何处理它。我们需要从论证中推断出T
,但论证没有类型 - 那么我们可以推导出什么类型呢?
在这种情况下,使其工作的方法是明确提供该T
:
bar<X>({0}); // ok
或者提供一个具有可以推导的类型的参数:
bar(X{0}); // ok
在原始示例中,您可以直接提供A
:
make_unique<B>(A{5})
或直接B
:
make_unique<B>(B({5}))
或者只使用new
:
unique_ptr<B>(new B({5}))
或者,不太受欢迎且有些可疑,明确指定模板参数:
make_unique<B, A>({5});
具有单个非默认参数(直到 C++11)的构造函数,该参数在没有函数说明符的情况下声明explicit
称为转换构造函数。您的A
和B
是此类构造函数的实例(这解释了为什么您的第一次调用工作正常。问题是,std::make_unique
阻碍了这些显式调用。无论如何,首先不信任这些自动创建并花费一些字符来显示类型可能是个好主意。这可以提高代码的可读性。
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 构造函数正在调用一个使用当前类类型的函数
- 如何修复函数样式强制转换或类型构造的预期"("?
- 具有默认模板类型的默认构造函数的类型推导
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 不命名构造函数和析构函数上的类型错误
- 具有自定义构造函数 (C++) 的类型的动态数组分配
- C++方法是否可以根据传递给构造函数的参数具有不同的返回类型?
- 创建类类型的动态分配数组,其中类不得具有默认构造函数
- 初始化自定义类型构造函数的数组
- OpenGL着色器错误C1068:类型构造函数中的数据过多
- Lambda 闭包类型构造函数
- 仅当基础类型具有模板类型构造函数时,才实现这些构造函数
- 模板类的构造函数在使用 new 关键字时调用类型构造函数
- 如何强制函数参数为相同类型,并且不允许使用类型构造函数与给定类型匹配
- 模板类型构造函数参数
- 它们是c++中的类型构造函数
- 解析C++类型构造函数