Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining an Inner class member function template with a (non type) enum argument

I'm having difficulty defining and specializing a member function update() of an inner class Outer<T1>::Inner that is templated on a non-type (enum) argument.

#include <cstdlib>

template<typename T1>
struct Outer
{
    struct Inner
    {
        enum Type{ A , B , C };

        template<Type T2>
        void update();
    };
};

// Definition
template<typename T1>
template<Outer<T1>::Inner::Type T2>
void Outer<T1>::Inner::update()
{
}

// Specialization
template<typename T1>
template<Outer<T1>::Inner::A >
void Outer<T1>::Inner::update()
{
}

int main()
{
    return EXIT_SUCCESS;
}

I'm getting the following error message in GCC 4.5.3

prog.cpp:17:28: error: ‘Outer::Inner::Type’ is not a type
prog.cpp:18:6: error: prototype for ‘void Outer<T1>::Inner::update()’ does not match any in class ‘Outer<T1>::Inner’
prog.cpp:11:15: error: candidate is: template<class T1> template<Outer<T1>::Inner::Type T2> void Outer<T1>::Inner::update()
prog.cpp:24:28: error: ‘Outer::Inner::A’ is not a type
prog.cpp:25:6: error: prototype for ‘void Outer<T1>::Inner::update()’ does not match any in class ‘Outer<T1>::Inner’
prog.cpp:11:15: error: candidate is: template<class T1> template<Outer<T1>::Inner::Type T2> void Outer<T1>::Inner::update()

BTW, unlike GCC, Visual Studio 2008 is unable to compile the following

template<typename T1>
struct Outer
{
    struct Inner
    {
        enum Type{ A , B , C };

        template<Type T2>
        struct Deep;
    };
};

template<typename T1>
template<typename Outer<T1>::Inner::Type T2>
struct Outer<T1>::Inner::Deep
{
};
like image 457
Olumide Avatar asked Feb 08 '13 16:02

Olumide


People also ask

What is a non type template parameter?

A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument. A non-type parameter can be any of the following types: An integral type. An enumeration type. A pointer or reference to a class object.

How do I restrict a template type in C++?

There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.

What are template arguments enlist types of template arguments?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)

What is a template template parameter in C++?

In C++ this can be achieved using template parameters. A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.


1 Answers

First of all, you're missing a typename before Outer<T1>::Inner::Type. You have to have it, even in a template type list, because Type is a dependent type.

Secondly, your specialisation syntax is wrong (the type goes in <> after the function name before the parentheses, not in the template<>), but even if it was correct, it would not be legal. You have to specialise the outer template Outer before you can fully specialise update, according to an unfortunate rule regarding explicit template specialisation.

like image 121
Seth Carnegie Avatar answered Sep 27 '22 22:09

Seth Carnegie