Это не дубликат Самый неприятный разбор: почему не A a (()); Работа?, который основан на разборе в виде A a(());
, чья OP мысль сможет построить по умолчанию A
объект, используя дополнительный набор скобок.
Напротив, мой вопрос о 2 классах, f
а также g
, где f
имеет конструктор по умолчанию и g
Ктор принимает f
, Я хочу позвонить g
Ктор с временным f
аргумент, все без использования единого синтаксиса инициализации. Есть std::cout
заявление в g
ctor, поэтому отсутствие вывода означает объявление функции вместо g
создание объекта. Я прокомментировал пример кода с 3 цифрами в комментариях. # 1 и # 2 были скомпилированы с # 3 закомментированными, и наоборот:
#include <iostream>
struct f {};
struct g {
g(f) { std::cout << "g's ctor\n"; }
};
int main() {
// -----Output-----
g( f() ); // #1: function declaration; expected
g( ( f() ) ); // #2: also a function declaration; UNEXPECTED
// g myG( ( f() ) ); // #3: "g's ctor" ONLY if #1 & #2 are commented out;
// ^ ... linker error otherwise
}
# 1: Я думал, что # 1 объявляет анонимную функцию, которая возвращает g
и принимает указатель на функцию, которая принимает 0 аргументов и возвращает f
, Я ошибся?
# 2: Итак, я думал, что дополнительный набор скобок в # 2 заставит заключенное содержимое быть оцененным как вызов функции, а именно вызов f
ctor по умолчанию. Но это все еще объявление функции. Зачем?
# 3: вариант # 2, где разница — добавленное имя экземпляра # 3 myG
, # 3 создает объект, если # 1 и # 2 закомментированы. В противном случае я получаю эти ошибки в VC12:
error LNK2019: unresolved external symbol "struct g __cdecl f(void)" (?f@@YA?AUg@@XZ) referenced in function _main
а также
fatal error LNK1120: 1 unresolved externals
,
и эта ошибка в g ++ 4.8: undefined reference to 'f()'
Что они имеют в виду, и почему я их получаю?
Почему # 3 является экземпляром объекта, только когда экземпляр назван?
Как получить желаемый эффект создания экземпляра, не называя экземпляр или используя единую инициализацию?
Первый объявляет функцию с именем f
не принимает параметров и возвращает g
,
g( f() );
// ^ ^ redundant set of parentheses
Второй — тот же, с еще одним избыточным набором скобок (помните, что вы можете иметь столько объявлений тех же функций, сколько пожелаете). Хотя они не всегда бесполезны. Они нужны, скажем, для объявления функции, которая возвращает указатель на функцию:
// function taking an int and returning
// a pointer to a function that takes a char
// and returns a g
g ( *f(int) )(char);
//^ ^ needed, syntax error without them
Что касается третьего:
Когда # 1 и # 2 есть, у вас есть объявление функции для f
в main
а также g myG( ( f() ) );
анализируется как объявление объекта типа g
по имени myG
и инициализируется в результате вызова функции. Вы получаете ошибку компоновщика, потому что нет определения для f
,
Когда # 1 и # 2 закомментированы, тип f
видно, и устранение неоднозначности с круглыми скобками:
g myG( ( f() ) )
// ^ ^ these force an expression
Без этой пары вы получили бы другое объявление функции.
То, что вы хотите, это:
( g(f()) );
// ^ ^ must be an expression as declarations can't be parenthesized
или что-то менее Lisp-ы: static_cast<g>(f());
Других решений пока нет …