Почему анонимным объектам иногда требуется конструктор по умолчанию?

Если я напишу следующую программу, она будет работать так, как я ожидаю:

struct Foo {
    Foo (std::string x) { std::cout << x << std::endl; }
};

int main () { Foo("hello, world"); }

Однако, если я пишу немного другую программу, я получаю ошибку компиляции:

struct Foo {
    Foo (std::string x) { std::cout << x << std::endl; }
};

std::string x("hello, world");

int main () { Foo(x); }

Ошибка:

prog.cc: In function 'int main()':
prog.cc:10:20: error: no matching function for call to 'Foo::Foo()'

Полная ошибка может быть замечена на IDEONE.

Почему ошибка возникает для второй программы, а не для первой?

3 ответа

Решение

Вы объявили переменную x с типом Foo

struct Foo {
    Foo(){}
    Foo (std::string x) { std::cout << x << std::endl; }
    void test(){ std::cout << "test" << std::endl; };
};

std::string x("hello, world");

int main () { Foo(x); x.test(); }

печать "тест"


Вы хотите использовать единый синтаксис инициализации Foo{x}

struct Foo {
    Foo (std::string x) { std::cout << x << std::endl; }
};

std::string x("hello, world");

int main () { Foo{x}; }

печать "привет, мир"

Foo(x); означает так же, как Foo x;, Вы можете добавить лишние скобки к имени переменной.

Итак, вам нужен конструктор по умолчанию, потому что это создает переменную x без аргументов, передаваемых конструктору.

Вы можете обойти это, выполнив Foo{x}; в C++11.

Правило синтаксического анализа состоит в том, что если что-то может быть действительным объявлением и действительным заявлением без объявления, то это фактически объявление. Смотрите также самый неприятный анализ

Я полностью согласен с вышеуказанным решением. Хотя это все еще будет работать:

struct Foo {
    Foo (string x) 
    { 
        cout << x << endl; 
    }
};


int main () 
{ 
    string x = "hello, world";
    Foo * abc = new Foo(x); 
    return 0;
}
Другие вопросы по тегам