Объектная неоднозначность объявления Конструкции/Функции переадресации

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.

7
задан Community 23 May 2017 в 12:13
поделиться

3 ответа

Это известно как «самый неприятный синтаксический анализ C ++». См. здесь и здесь .

6
ответ дан 7 December 2019 в 05:22
поделиться

Давайте немного упростим.

int f1();

Что это? Компилятор (и я) говорят, что это предварительное объявление функции, возвращающей целое число.

Как насчет этого?

int f2(double );

Компилятор (и я) говорят, что это прямое объявление функции, принимающей аргумент типа double и возвращающей int.

Вы пробовали это:

ClassType c = ClassType(ArgType());

Ознакомьтесь с c ++ faq lite по конструкторам , чтобы найти объяснения и примеры

1
ответ дан 7 December 2019 в 05:22
поделиться

Исходя из «C ++ 0x разрешен», правильный ответ (вероятно) - изменить определение на:

Class c(ArgType {});

Просто, понятно и полностью возлагает бремя на пользователя библиотеки, а не на автора!

Edit: Да, вызывается ctor - C ++ 0x добавляет List-Initialization как однозначный способ разграничения списков инициализаторов. Его нельзя неправильно проанализировать, как в вашем примере, но в остальном значение примерно такое же, как если бы вы использовали круглые скобки. См. N3000 , третий пункт в §8.5.4 / 3. Вы можете написать ctor для получения списка инициализаторов в виде одного аргумента, или элементы в списке инициализаторов могут быть сопоставлены с аргументами ctor по отдельности.

1
ответ дан 7 December 2019 в 05:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: