C++ 有没有一种不用std::move就用构造的类初始化类的方法? //示例程序 #包括 #包括 #包括 甲级{ 公众: int x; }; B类{ 公众: B(A&&A):m_A(std::move(A)){} A m_A; }; int main() { B变量(std::move(A()); //B var(A());//不编译为什么? std::cout

C++ 有没有一种不用std::move就用构造的类初始化类的方法? //示例程序 #包括 #包括 #包括 甲级{ 公众: int x; }; B类{ 公众: B(A&&A):m_A(std::move(A)){} A m_A; }; int main() { B变量(std::move(A()); //B var(A());//不编译为什么? std::cout,c++,C++,这个问题被称为,它准确地描述了您的情况,解析器不知道您是否需要函数声明或对象的实例化。从某种意义上讲,它是不明确的,对于人来说,某个给定的代码段执行X,但对于编译器来说,它显然执行Y 一种解决方法是使用以下语法: 这不再是模棱两可的,它将根据您的需要调用构造函数。您也可以在A中使用它,或者在两者中都使用它: B var{A()}; // note the use of brackets 现在,为什么它是不明确的?例如,函数参数的声明是函数的指针: 这里,参数的类型为指向函数的指针,不带参数,返

这个问题被称为,它准确地描述了您的情况,解析器不知道您是否需要函数声明或对象的实例化。从某种意义上讲,它是不明确的,对于人来说,某个给定的代码段执行X,但对于编译器来说,它显然执行Y

一种解决方法是使用以下语法:

这不再是模棱两可的,它将根据您的需要调用构造函数。您也可以在
A
中使用它,或者在两者中都使用它:

B var{A()}; // note the use of brackets
现在,为什么它是不明确的?例如,函数参数的声明是函数的指针:

这里,参数的类型为指向函数的指针,不带参数,返回类型为int。另一种声明指向函数指针的方法是省略声明符中的括号:

int foo(int (*bar)());
它仍然声明指向与前一个相同的函数的指针。由于我们在声明参数()的上下文中,正在解析的语法是a,它部分构建在上一个之上。因此,这允许我们删除标识符:

int foo(int bar());
我们最终还是得到了同样的类型

说到这里,让我们检查一下您的代码,并将其与上面的示例进行比较:

int foo(int());
我们有一个类似于
B
类型的变量声明,它是用
a()
初始化的。到目前为止,还不错。但是,等等,你说它不能编译

错误消息显示,它将var视为函数声明

B var(A{});
var
实际上是一个函数声明,尽管对您来说,它一开始看起来不是这样的。这种行为是由于:

该决议是考虑任何可能构成声明的构造。
B var(A{});
这句话适用于这里。回顾前面的例子:

B var(A());
这和您的代码一样模糊:
foo
可能是一个声明,因此解决方案是将其解释为一个声明。您的
bvar(a())
也可能是一个声明,因此它具有相同的解决方案

该标准提供了一些此类案例的示例,还提供了一些关于如何消除歧义的提示:

[ 注意:可以通过在参数周围添加括号来明确消除声明的歧义。 通过使用复制初始化或列表初始化语法,或使用非函数样式转换,可以避免歧义。 — 尾注  ]

[ 例如:

int foo(int());
- 结束示例  ]


而是像这样构造你的
A

struct S {
  S(int);
};

void foo(double a) {
 S w(int(a));                  // function declaration
 S x(int());                   // function declaration
 S y((int(a)));                // object declaration
 S y((int)a);                  // object declaration
 S z = int(a);                 // object declaration
}
对于函数声明,它不会被混淆

B var(A{});
假设
B(A&&)
构造函数不是
显式的
(在您的情况下,它不是,因此,它是一种工作方法)

这也是一种解决问题的有效方法

<>编译器认为你的原始行是函数声明,因为在C++中,你可以在本地声明任何函数,甚至函数或结构:

B var(A{});
就你而言:

int f()
{
   void f(); // You declare that function exists.
   class C; // You declare a class called `C` exists.
}
编译器看到它存在一个名为
var
的函数,返回一个
B
,并接收一个不接收参数但返回一个
a
的函数

您必须使用上述两种方法中的任何一种来消除歧义

int f()
{
   void f(); // You declare that function exists.
   class C; // You declare a class called `C` exists.
}
B var(A());