做一些奇怪的事情的c ++匿名构造函数

Eri*_*ing 5 c++ anonymous default-constructor

此示例程序显示如何调用不同的构造函数,具体取决于是传入局部变量,全局变量还是匿名变量.这里发生了什么?

std::string globalStr;
class aClass{
public:
  aClass(std::string s){
    std::cout << "1-arg constructor" << std::endl;
  }
  aClass(){
    std::cout << "default constructor" << std::endl;
  }
  void puke(){
    std::cout << "puke" << std::endl;
  }
};

int main(int argc, char ** argv){
  std::string localStr;
  //aClass(localStr); //this line does not compile
  aClass(globalStr);  //prints "default constructor"
  aClass(""); //prints "1-arg constructor"
  aClass(std::string("")); //also prints "1-arg constructor"
  globalStr.puke(); //compiles, even though std::string cant puke.
}
Run Code Online (Sandbox Code Playgroud)

鉴于我可以调用globalStr.puke(),我猜测通过调用aClass(globalStr);,它正在创建一个名为globalStrtype 的局部变量aClass,而不是全局变量globalStr.调用aClass(localStr);尝试执行相同的操作,但无法编译,因为localStr已经声明为std::string.是否可以通过使用非常量表达式调用其1-arg构造函数来创建类的匿名实例?谁决定type(variableName);应该是一个可接受的方法来定义一个名为variableName?的变量?

chr*_*ris 11

aClass(localStr); //this line does not compile
Run Code Online (Sandbox Code Playgroud)

这会尝试声明一个aClass名为的变量localStr.语法很糟糕,我同意,但现在已经太晚了[改变标准].

aClass(globalStr);  //prints "default constructor"
Run Code Online (Sandbox Code Playgroud)

这声明了一个叫做的globalStr.这个globalStr变量隐藏了全局变量.

aClass(""); //prints "1-arg constructor"
Run Code Online (Sandbox Code Playgroud)

这将创建一个类型的临时对象aClass.

aClass(std::string("")); //also prints "1-arg constructor"
Run Code Online (Sandbox Code Playgroud)

这也创造了一个暂时的.

globalStr.puke(); //compiles, even though std::string cant puke.
Run Code Online (Sandbox Code Playgroud)

这使用globalStrin main,这与每个其他阴影实例一致.

是否可以通过使用非常量表达式调用其1-arg构造函数来创建类的匿名实例?

是的,我可以想到四种方式:

aClass{localStr}; // C++11 list-initialization, often called "uniform initialization"
(void)aClass(localStr); // The regular "discard this result" syntax from C.
void(aClass(localStr)); // Another way of writing the second line with C++.
(aClass(localStr)); // The parentheses prevent this from being a valid declaration.
Run Code Online (Sandbox Code Playgroud)

作为旁注,这种语法通常可能是最令人烦恼的解析的原因.例如,以下声明一个foo返回的函数aClass,其中一个参数localStr类型为std::string:

aClass foo(std::string(localStr));
Run Code Online (Sandbox Code Playgroud)

事实上,对你的问题负责的是相同的规则 - 如果某些东西可以被解析为有效的声明,它必须是.这就是为什么aClass(localStr);声明而不是由单独表达组成的声明.