Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using declaration for type-dependent template name

When CRTP is used inside a template, (or generally when a template parameter is passed as a base class template argument), is it impossible to name the base's member templates in a using declaration?

template< typename d >
struct base {
    template< typename >
    struct ct {};

    template< typename >
    void ft() {}
};

template< typename x >
struct derived : base< derived< x > > {
     using derived::base::template ct; // doesn't work
     using derived::base::ft; // works but can't be used in a template-id
};

It seems to me that this is a hole in the language, simply because the using-declaration grammar production doesn't incorporate a qualified-id.

using-declaration:
    using typename(opt) nested-name-specifier unqualified-id ; // have this
    using :: unqualified-id ;

unqualified-id:
    identifier
    operator-function-id
    conversion-function-id
    literal-operator-id
    ~ class-name
    ~ decltype-specifier
    template-id

qualified-id:
    nested-name-specifier template(opt) unqualified-id // want this
    :: identifier
    :: operator-function-id
    :: literal-operator-id
    :: template-id

If the only rule were using-declaration: using typename(opt) qualified-id, the only consequences would be

  • ruling out :: conversion-function-id, :: ~ class-name, and :: ~ decltype-specifier template-id which make no semantic sense,
  • allowing :: template-id which is already expressly forbidden by 7.3.3/5, and
  • allowing the template keyword which already has sufficient specification to patch the hole.

Is this analysis correct?

Given that the new grammar were allowed, perhaps a declaration with typename should import a class template or alias template, and one without typename should import a function or variable template into the current scope.

     using typename derived::base::template ct;
     using derived::base::ft;

This might require some additional specification. Also, the current status quo seems to be that dependent template-names always have ambiguous kind (not template-ids), so it's not clear that typename belongs with ct at all.

like image 777
Potatoswatter Avatar asked Mar 15 '13 01:03

Potatoswatter


People also ask

What is dependent name example?

A dependent name is a name that depends on the type or the value of a template parameter. For example: template<class T> class U : A<T> { typename T::B x; void f(A<T>& y) { *y++; } }; The dependent names in this example are the base class A<T> , the type name T::B , and the variable y .

Which is Dependant on template parameter?

Which is dependant on template parameter? Explanation: Base class is dependant on template parameter.

What is the correct form of declaring a template in C++?

Class Template Declarationtemplate <class T> class className { private: T var; ... .. ... public: T functionName(T arg); ... .. ... }; In the above declaration, T is the template argument which is a placeholder for the data type used, and class is a keyword.

How do you declare a template?

To instantiate a template class explicitly, follow the template keyword by a declaration (not definition) for the class, with the class identifier followed by the template arguments. template class Array<char>; template class String<19>; When you explicitly instantiate a class, all of its members are also instantiated.


1 Answers

The following works fine with C++11:

#include <iostream>

template< typename d >
struct base {
    template< typename >
    struct ct {};

    template< typename >
    void ft() {std::cerr << "cheesecake" << std::endl;}
};

template< typename x >
struct derived : base< derived< x > > {
  template<typename X>
    using ct = typename derived::base::template ct<X>; // new in C++11
  using derived::base::ft;
};

int main()
{
  derived<int>::ct<float> c;
  derived<int> a;
  a.ft<int>();
}

If that is not what you wanted, can you please give an example of how you would want to use ct and ft?

like image 139
Rumburak Avatar answered Sep 20 '22 19:09

Rumburak