C ++ анонимный конструктор делает странные вещи

В этом примере программы показано, как будет вызываться другой конструктор, в зависимости от того, передаете ли вы локальную переменную, глобальную переменную или анонимную переменную. Что здесь происходит?

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.
}

Учитывая, что я могу позвонить globalStr.puke()Я предполагаю, что позвонив aClass(globalStr);создает локальную переменную с именем globalStr типа aClass который используется вместо глобального globalStr, призвание aClass(localStr); пытается сделать то же самое, но не компилируется, потому что localStr уже объявлен как std::string, Можно ли создать анонимный экземпляр класса, вызвав его 1-аргументный конструктор с неконстантным выражением? Кто решил что type(variableName); должен быть приемлемым способом определения переменной с именем variableName?

6

Решение

aClass(localStr); //this line does not compile

Это пытается объявить переменную типа aClass названный localStr, Синтаксис ужасен, я согласен, но сейчас слишком поздно для этого [изменения стандарта].

aClass(globalStr);  //prints "default constructor"

Это объявляет один называется globalStr, это globalStr переменная скрывает глобальную.

aClass(""); //prints "1-arg constructor"

Это создает временный объект типа aClass,

aClass(std::string("")); //also prints "1-arg constructor"

Это также создает временный характер.

globalStr.puke(); //compiles, even though std::string cant puke.

Это использует globalStr в main, что согласуется с любым другим случаем слежки.

Можно ли создать анонимный экземпляр класса, вызвав его 1-аргументный конструктор с неконстантным выражением?

Да, я могу придумать четыре способа:

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.

Как примечание, этот синтаксис часто может быть причиной самого разборчивого разбора. Например, следующее объявляет функцию foo это возвращает aClassс одним параметром localStr типа std::string:

aClass foo(std::string(localStr));

На самом деле это то же правило, которое отвечает за ваши проблемы — если что-то может быть проанализировано как правильное объявление, так и должно быть. Поэтому aClass(localStr); является объявлением, а не утверждением, состоящим из одного выражения.

12

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector