Обычно typename
используется для устранения неоднозначности между случаями, когда идентификатор может относиться к типу или может относиться к чему-то другому:
template<class T>
void foo(typename T::type value) {
// ...
}
Когда можно использовать typename
, когда идентификаторуже тип?
1. Можно ли его использовать, если класс с таким именем уже существует?
class MyClass{};
void foo(typename MyClass value) {}
2. Может ли ониспользоваться с параметром шаблона, объявленным как тип?
template<class T>
void foo(typename T value) {}
3. Может ли он использоваться с внутренними классами, которые однозначно являются типами?
class A {
public:
class B {};
};
// Compiles; no typename necessary
void foo(A::B value) {}
// This compiles too on gcc and msvc
void bar(typename A::B value) {}
Интерпретация
Случай 1: MSVC считает, что это нормально;gcc и clang выдают ошибку
Случай 2: MSVC считает это нормально;gcc и clang выдают ошибку
Случай 3: A::B
однозначно является типом, но gcc и clang теперь разрешают использовать typename
.