Is typename required or not?

Consider the code:

#include <memory> template <class T, class Deleter = std::default_delete<T>> class unique_ptr_wrapper: public std::unique_ptr<T, Deleter> { public: using typename std::unique_ptr<T, Deleter>::unique_ptr; operator T* () const {return this->get();} }; int main() { unique_ptr_wrapper<int> upw{new int{42}}; } 

g ++ 5.1 compiles it well, although clang ++ complains

error: typename is allowed only for identifiers

I agree that we do not have an identifier here, so typename probably not required. But is it really forbidden? Does the compiler need to at least fix the diagnostics?

EDIT Code compiled without typename using g ++ and clang ++.


UPDATE . This seems to be a g ++ bug, I reported it here .

+4
source share
1 answer

[class.inhctor] / p1, my emphasis:

Use-declarations (7.3.3), which does not specify a constructor, implicitly declares a set of inheriting constructors.

The constructor is not a type.

[temp.res] / p3-4:

3 When a qualified identifier is intended to indicate a type that is not a member of the current instance (14.6.2.1) and its inested-name-specifier refers to a dependent type, it must be prefixed with the keyword typename , forming a qualifier-name-type. If the identifier with the qualification-id in the typename-specifier does not indicate a type, the program is poorly formed.

4 If a template specialization is created for a set of template arguments, so that the identifier with the id qualification, the prefix typename does not indicate type, the specialization is poorly formed. A regular name lookup (3.4.3) is used to search for identified-id even in the presence of typename .

[class.qual] / r2

In a search in which function names are not ignored, and the Nested Qualifier name assigns the class C :

  • if the name specified after the nested qualifier name, when searching in C , is the entered name of the class C (section 9) or

  • in the declaration of use (7.3.3), which is a participantโ€™s declaration, if the name indicated after the embedded qualifier name matches the identifier name or the template name simple-template-id in the last component of the embedded qualifier name,

instead, the name is considered the name of the constructor of class C

Applying the rules of the usual plain name lookup found in [class.qual], std::unique_ptr<T, Deleter>::unique_ptr names the constructor. It does not indicate type. Therefore, according to the above quote from [temp.res], the program is poorly formed (diagnostics required).

In other words, this seems like a GCC bug (although the Clang error message may also use some improvement).

+8
source

Source: https://habr.com/ru/post/988251/


All Articles