Ответ 1
Да, это работает, и причина - механизм поиска имени. Механизм объявления наследования-конструкторов прост: если имя используемого объявления относится к конструкторам базового класса, это объявление наследования конструкторов. В 3.4.3.1 [class.qual] p2 находим:
В поиске, в котором конструктор является приемлемым результатом поиска, а спецификатор вложенных имен назначает класс C
- если имя, указанное после вложенного имени-спецификатора, при поиске на C, является введенным классом-именем C (раздел 9) или
- в декларации using (7.3.3), которая является объявлением-членом, если имя, указанное после спецификатора вложенных имен, совпадает с идентификатором или именем шаблона-шаблона в последнем компонент спецификатора вложенных имен
вместо этого вместо имени будетменоваться конструктор класса C.
Это абзац, который делает из определений конструктора классов, и это также абзац, который делает наследование объявлений конструкторами. В этом случае применяется вторая пуля:
struct B {
B(int) { }
};
typedef B mytype;
struct A : B {
// "name ... is the same as the identifier ... in the last component ..."
using mytype::mytype;
};
template<typename T> using same = T;
struct C : B {
// "name ... is the same as the template-name ... in the last component ..."
same<B>::same;
};
Последний пример также полезен в таких случаях, как следующее
template<template<typename> class Base>
struct X : Base<int> {
using Base<int>::Base;
};
Вкратце:
-
Первая пуля выше - это семантическое правило - если имя после вложенного спецификатора имени относится к имени введенного класса (
B::B
илиmytype::B
), тогда оно будет переведено на ссылку на конструктор ( с). -
Вторая пуля - это синтаксическое правило - имена должны просто совпадать - их значение не имеет значения в противном случае - в аргументе шаблона, предоставленном
X
, может быть член с именемBase
, например, в следующее, но объявление using все равно будет импортировать конструкторы и не называть элементBase
:template<typename T> struct D { private: T Base; }; X<D> x; // valid, the private member is *not* touched!