2015-11-23 3 views
5

В соответствии с ответами, полученными мной here, приведенный ниже код плохо сформирован, несмотря на то, что clang и vs2015 принимают его.Попытка понять [class.qual]/2 в стандарте C++

#include <iostream> 
class A { 
public: 
    A() { std::cout << "A()" << '\n'; } 
}; 

int main() 
{ 
    A::A(); 
} 

Тем не менее, ниже код, кажется, работает во всех 3-компиляторов (см live example). AFAICT, согласно [class.qual/2], код плохо сформирован. Или я чего-то не хватает?

#include <iostream> 
struct B { B() { std::cout << "B()" << '\n'; } }; 
struct A : public B { }; 
int main() 
{ 
    A::B(); 
} 

Кроме того, в соответствии с [class.qual]/2, приведенный ниже код хорошо сформирован и в этом случае, все 3 составители производят ожидаемый результат (смотри пример here).

include <iostream> 
struct B { B() { std::cout << "B()" << '\n'; } }; 
struct A : public B { using B::B; A() { std::cout << "A()" << '\n'; } void f() { B(); } }; 
int main() 
{ 
    A a; 
    a.f(); 
} 

Выход:

B() 
A() 
B() 

Но я хотел бы знать, что это Полезность с использованием декларирования именами конструктора, как один (using B::B;) в классе выше A. Обратите внимание, что это с использованием декларации совершенно не имеет отношения к этому случаю, независимо от того, является ли B базовым классом A, или нет.

ответ

3

Я думаю, что ваш второй образец хорошо сформирован. В правиле в [class.qual]/2 указано, что имя ссылается на конструктор, если имя, указанное после вложенного имени-спецификатора при поиске в C, является введенным классом-именем C. В случае A::B имя, указанное после вложенного имени-спецификатора, представляет собой введенное имя класса B (видимое из-за наследования), а не A. В этом случае A::B однозначно называет тип, A::B() создает временный экземпляр B.

Использование деклараций именования конструкторов может быть полезным для продвижения базового класса конструкторов, которые принимают аргументы:

struct B { B(int a) { std::cout << "B " << a << '\n'; } }; 
struct A : public B { using B::B; }; 
int main() 
{ 
    A a{1}; //would not be valid without the using-declaration 
} 
+0

Ваш пример выше, кажется, чтобы подтвердить, что вы говорите. Но можете ли вы предоставить цитату из стандарта, поддерживающего эту конструкцию. Я никогда не видел эту конструкцию раньше. – Belloc

+0

Стандартизация немного длинна для того, чтобы вставить его в мой вопрос, но вы, вероятно, захотите посмотреть на '[class.inhctor]' – TartanLlama

+0

После быстрого изучения [class.inhctor] я должен согласиться с вами. Кажется, ответ на мой второй вопрос (+1). Но я до сих пор не уверен в моем первом вопросе. – Belloc

Смежные вопросы