Observation: the codes pasted below were tested only with GCC 4.4.1, and I'm only interested in them working with GCC.
Здравствуйте,
Это не было в течение всего нескольких раз, что я споткнулся в объектный оператор конструкции, который я не понял, и это было только сегодня, что я заметил, какая неоднозначность представлялась им. Я объясню, как воспроизвести его и хотел бы знать, существует ли способ зафиксировать его (C++ 0x позволенный). Здесь это идет.
Предположим, что существует класс, конструктор которого берет только один аргумент, и тип этого аргумента является другим классом с конструктором по умолчанию. Например:
struct ArgType {};
class Class
{
public:
Class(ArgType arg);
};
Если я пытаюсь создать объект типа Class
на стеке я получаю неоднозначность:
Class c(ArgType()); // is this an object construction or a forward declaration
// of a function "c" returning `Class` and taking a pointer
// to a function returning `ArgType` and taking no arguments
// as argument? (oh yeh, loli haets awkward syntax in teh
// saucecode)
Я говорю, что это - объектная конструкция, но компилятор настаивает, что это - предописание в теле функции. Для Вас, кто все еще не получает его, вот полностью рабочий пример:
#include
struct ArgType {};
struct Class {};
ArgType func()
{
std::cout << "func()\n";
return ArgType();
}
int main()
{
Class c(ArgType());
c(func); // prints "func()\n"
}
Class c(ArgType funcPtr()) // Class c(ArgType (*funcPtr)()) also works
{
funcPtr();
return Class();
}
Так хорошо, достаточно примеров. Кто-либо может помочь мне обойти это, ничего не делая слишком антиидиоматичным (я - разработчик библиотеки и люди как идиоматические библиотеки)?
- редактирование
Неважно. Это - простофиля Самого раздражающего синтаксического анализа: почему не делает (()); работа?.
Спасибо, sbi.
Давайте немного упростим.
int f1();
Что это? Компилятор (и я) говорят, что это предварительное объявление функции, возвращающей целое число.
Как насчет этого?
int f2(double );
Компилятор (и я) говорят, что это прямое объявление функции, принимающей аргумент типа double и возвращающей int.
Вы пробовали это:
ClassType c = ClassType(ArgType());
Ознакомьтесь с c ++ faq lite по конструкторам , чтобы найти объяснения и примеры
Исходя из «C ++ 0x разрешен», правильный ответ (вероятно) - изменить определение на:
Class c(ArgType {});
Просто, понятно и полностью возлагает бремя на пользователя библиотеки, а не на автора!
Edit: Да, вызывается ctor - C ++ 0x добавляет List-Initialization как однозначный способ разграничения списков инициализаторов. Его нельзя неправильно проанализировать, как в вашем примере, но в остальном значение примерно такое же, как если бы вы использовали круглые скобки. См. N3000 , третий пункт в §8.5.4 / 3. Вы можете написать ctor для получения списка инициализаторов в виде одного аргумента, или элементы в списке инициализаторов могут быть сопоставлены с аргументами ctor по отдельности.