使用标准构造函数传递临时对象
Pass temporary object with standard constructor
>我想将一个临时对象(例如 std::string(传递给我的对象的构造函数:
class MyClass{
public:
MyClass(string a):
a(a)
{
}
string a;
};
int main(int argc, char *argv[]){
MyClass a(string());
cout<<a.a<<endl;
return 0;
}
但是我收到此错误:
main.cpp: In function ‘int main(int, char**)’:
main.cpp:28:11: error: request for member ‘a’ in ‘a’, which is of non-class type ‘MyClass(std::string (*)()) {aka MyClass(std::basic_string<char> (*)())}’
如果我将任何东西传递给临时对象的构造函数(例如 string("((,一切正常。为什么?
这是被称为C++最令人烦恼的解析的一个实例。编译器解释
MyClass a(string());
作为名为 a
的函数的原型,返回一个MyClass
并将未命名的string
作为参数。
您可以通过在对 string
构造函数的调用两边加上括号来消除歧义:
MyClass a((string()));
或者,只要MyClass
具有可访问的复制构造函数:
MyClass a = string();
C++11 更新
你也可以用通用初始化语法消除歧义,只要你的类没有接受initializer_list
的构造函数:
MyClass a { string() };
正如 Seth 已经指出的那样,这是语言和表达式解析方式的问题。基本上,当编译器找到表达式MyClass a(string())
它将其解释为具有签名MyClass (std::string (*)())
的函数a
的声明(额外的(*)
来自参数中从函数到指针再到函数的隐式转换(。
在您的特定情况下,有不同的方法可以克服该语法:
MyClass a(""); // 1
MyClass b = std::string(); // 2
MyClass c(( std::string() )); // 3
第一种方法不是使用 T()
表达式来创建 rvalue,而是使用将产生相同输出的常量文本。这种方法的缺点是,在这种特殊情况下,您可以使用文本,但相同的解决方案不能应用于其他类型(即,如果您自己的类型只有一个默认构造函数(
第二种方法是避免直接初始化,因为替代语法不能解析为函数声明。这种方法的问题在于,虽然特定情况下的结果是相同的,但它要求构造函数不是显式的。(即,如果您的构造函数被声明为 explicit MyClass( std::string const & )
,它将失败(,但它不是
第三种方法是在构造函数的第一个参数周围添加一组额外的括号(请注意,解析中的相同问题也会发生在MyClass a(std::string(), std::string())
上(。这种方法(意见(的问题在于它很丑陋,但在其他方面它是三者中最灵活的。
- 类中的 Arduino 对象构造函数设置垃圾值
- 编译错误:临时对象构造函数中缺少参数
- 双指针在使用 new 时不调用对象构造函数
- 以支持继承的方式将自身shared_ptr添加到对象构造函数中的向量中
- 在创建对象向量时,不为每个对象唯一调用默认对象构造函数
- GCC __attribute__((constructor)) 在对象构造函数之前调用
- 自定义对象构造函数在循环外部循环
- 从全局对象构造函数停止监视器计时器
- 如何防止使用临时调用构造函数
- Arduino 上的 Sketch 停止在对象构造函数中执行
- C++临时对象成员函数的生存期
- 通过在引用线程对象来传递取消引用的“this”指针来在函数对象构造函数中创建线程是好是坏
- 为什么当对象构造函数投入新表达式时,为什么不调用DealLocation函数
- 临时结构对象构造函数奇数调用
- 未显式引用对象的全局对象构造函数在最终二进制文件 - LD 中被丢弃
- 为什么 Clang++ 不在另一个静态库中运行全局对象构造函数?
- 在未加载上下文的情况下在对象构造函数中使用OpenGL函数
- 为什么我们需要一个用户提供的const对象构造函数
- 对象构造函数的C++数组
- 以临时对象为参数的C++对象构造函数