Расширение прямого вызова MSVC

В этом ответе tloveless указал, что в MSVC возможно использовать this->foo::foo(42); для делегирования конструктора для непосредственного вызова конструктора:

#include <iostream>

struct foo
{
    int m;
    foo(int p) : m(p) { std::cout << "foo("<<p<<")\n"; }
    foo()
        : m(0)
    {
        this->foo::foo(42);
        std::cout << "foo(), " << m << "\n";
    }
};

int main()
{
    foo f;
    std::cin.ignore();
}

Я был удивлен, что это даже компилируется в MSVC; clang++, g++ и я согласны с тем, что это незаконно, например, [class.ctor]/2 "Поскольку конструкторы не имеют имен, они никогда не будут найдены во время поиска по имени"

Тем не менее, MSVC даже не выдает предупреждение с /Wall и без языковых расширений /Za в MSVC12, обновление 1 (2013) и MSVC10 SP1 (2010).

Выход:

Foo(42)
foo(), 42

в обеих версиях. Так что нет никакого временного созданного, но конструктор называется.

Вопросы:

  1. Как называется это расширение?
  2. Разве это не считается расширением? (/Za и список расширений, кажется, так не думаю)
  3. Есть ли документация для / официального описания этой функции?

(Я пометил этот вопрос тегом [Delegating-Constructors], так как он сильно напоминает мне об этой функции)


Мета-информация: Я почти уверен, что этот вопрос является дубликатом, так как эта функция несколько известна. Например, посмотрите этот ответ на "похожий вопрос". Пожалуйста, не стесняйтесь закрывать это как дубликат, если вы можете найти ответ, который описывает эту функцию.

1 ответ

Это не делегирование конструктора. Попробуйте следующий код:

#include <iostream>

class C{
public:
    C() { std::cout << "C" << std::endl; }
    ~C() { std::cout << "~C" << std::endl; }
};

struct foo
{
    int m;
    C c;
    foo(int p) : m(p) { std::cout << "foo("<<p<<")\n"; }
    foo()
        : m(0)
    {
        this->foo::foo(42);
        std::cout << "foo(), " << m << "\n";
    }
};

int main()
{
    foo f;
}

Согласно выходному полю "c" инициализируется дважды, но уничтожается только один раз. Как отметил Знеак, это похоже на new (this) foo(42),

Другие вопросы по тегам