Durante la lettura this question, ho trovato uno strano punto:C++ utilizzando dichiarazione con la typename a ereditare-costruttori
template <typename T>
class Subclass : public Baseclass<T>
{
public:
using typename Baseclass<T>::Baseclass;
// ^^^^^^^^
};
Dal typename
, Baseclass<T>::Baseclass
dovrebbe essere injected class name, non un costruttore. Per quanto ne so, è lo stesso caso come questo:
template <typename T>
class Base
{
public:
typedef short some_type;
};
template <typename T>
class Sub : public Base<T>
{
public:
using typename Base<T>::some_type;
};
Per essere sicuri, ho scritto un codice di prova.
#include <iostream>
template <typename T>
class Base
{
public:
Base() { std::cout << "A::A()\n"; }
Base(int) { std::cout << "A::A(int)\n"; }
Base(const char *) { std::cout << "A::A(const char *)\n"; }
};
template <typename T>
class Sub : public Base<T>
{
using typename Base<T>::Base;
};
int main()
{
Sub<char> s1;
Sub<char> s2(3);
Sub<char> s3("asdf");
}
Tuttavia, gcc viene eseguito su 4.8.3.
$ g++ -std=c++1y -Wall -Wextra -Werror -pedantic test.cpp -o test && ./test
A::A()
A::A(int)
A::A(const char *)
Funziona anche senza typename
.
$ cat test.cpp
...
using Base<T>::Base;
...
$ g++ -std=c++1y -Wall -Wextra -Werror -pedantic test.cpp -o test && ./test
A::A()
A::A(int)
A::A(const char *)
Perché ho ottenuto questi risultati? Cosa mi sono perso?
clang ++ respinge il ' typename'. – dyp
Mi sono preoccupato troppo della mia sanità mentale per rispondere a questa domanda sull'altra domanda ... Lo standard dice in [namespace.udecl]/1 "Se una * using-declaration * nomina un costruttore, dichiara implicitamente un insieme di costruttori nel classe in cui appare * using-declaration *, altrimenti il nome specificato in * using-declaration * è un sinonimo di per il nome di qualche entità dichiarata altrove. " Ma in [class.ctor]/1 "I costruttori non hanno nomi". – dyp
Nota che c'è [spazio dei nomi.udecl]/20 "Se una * using-declaration * utilizza la parola chiave' typename' e specifica un nome dipendente, il nome introdotto dalla * using-declaration * è considerato come * typedef-name *. " – dyp