В качестве интересного продолжения (хотя и не имеющего большого практического значения) моего предыдущего вопроса: почему C ++ позволяет нам заключать имя переменной в круглые скобки при объявлении переменной?
Я обнаружил, что объединение объявления в круглых скобках с введенной функцией имени класса может привести к неожиданным результатам в отношении поведения компилятора.
Взгляните на следующую программу:
#include <iostream>
struct B
{
};
struct C
{
C (){ std::cout << "C" << '\n'; }
C (B *) { std::cout << "C (B *)" << '\n';}
};
B *y = nullptr;
int main()
{
C::C (y);
}
Компиляция с g ++ 4.9.2 дает мне следующую ошибку компиляции:
main.cpp:16:10: error: cannot call constructor 'C::C' directly [-fpermissive]
Он успешно компилируется с MSVC2013 / 2015 и печатает
C (B *)
Он успешно компилируется с clang 3.5 и печатает
C
Поэтому обязательный вопрос: какой из них правильный? :)
(Я сильно склонялся к версии clang, и способ msvc перестать объявлять переменную после простого изменения типа с технически его typedef кажется странным)
C::C
не называет тип, он называет функцию, так что GCC прав imo.
C::C y;
не имеет смысла, правда? И тоже.C::C (y);
Сначала я думал, что это экземпляр Most-Vexing-Parse stackoverflow.com/questions/tagged/most-vexing-parse , но теперь я думаю, что это просто неопределенное поведение, означающее, что все три компилятора «правы».