Почему анонимным объектам иногда требуется конструктор по умолчанию?
Если я напишу следующую программу, она будет работать так, как я ожидаю:
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;
}