Ricardo_arg
Ricardo_arg

Reputation: 520

c++11 -Template MetaProgramming - Error: template parameters not used in partial specialization

i am getting stuck with a partial template implementation, the idea is to provide a class (a builder) that is select at compile time using an enum class definition, also i want to provide the name of file and a class name for manage from the factory singleton. But this is not compiling, i am trying several hours, but i cannot see what i am doing wrong. This is the code:

enum class BuildersType
{
   ComunicationBuilder
};

//class definition
template<BuildersType, class ... Args>
class BuiderType;

//class implementation
template<const char * const FILENAME , const char *  const CLASSNAME, class ClassToConfigurate>
class BuiderType<BuildersType::ComunicationBuilder,const char * const ,const char * const ,ClassToConfigurate>
{
   public:

};

template<const char * const FILENAME , const char * const CLASSNAME>
class AnotherBuilder
{
};

namespace Test
{
   static constexpr char FILENAME []="aFileName";
   static constexpr char  CLASSNAME []="ClassName";
   class TestClass{};
}

int main()
{

   BuiderType<BuildersType::ComunicationBuilder,Test::FILENAME,Test::CLASSNAME,Test::TestClass> aBuilder;
   AnotherBuilder<Test::FILENAME,Test::CLASSNAME> aAnotherBuilder;
   return 0;
}

The compile ouput :

Error: template parameters not used in partial specialization:
 class BuiderType<BuildersType::ComunicationBuilder,const char * const ,const char * const ,ClassToConfigurate>
       ^
main.cpp:14:7: error:         'FILENAME'
main.cpp:14:7: error:         'CLASSNAME'

At this hours i am really tired, and i am asking help. Thx in advance //===================================================== For simplicity I will post the code with the solution:

enum class BuildersType
{
  ComunicationBuilder
};

//class definition
//Add here definition here of the templates non type arguments
template<BuildersType, const char * const FILENAME , const char *  const CLASSNAME,class ... Args>
class BuiderType;

//class implementation

template<const char * const FILENAME , const char *  const CLASSNAME, class ClassToConfigurate, class ... Args>
class BuiderType<BuildersType::ComunicationBuilder,FILENAME , CLASSNAME ,ClassToConfigurate,Args...>
{
public:

};
template<const char * const FILENAME , const char * const CLASSNAME>
class AnotherBuilder
{

};
namespace Test
{
static constexpr char FILENAME []="aFileName";
static constexpr char  CLASSNAME []="ClassName";
    class TestClass{};
}
int main()
{

    BuiderType<BuildersType::ComunicationBuilder,Test::FILENAME,Test::CLASSNAME,Test::TestClass> aBuilder;
    AnotherBuilder<Test::FILENAME,Test::CLASSNAME> aAnotherBuilder;
return 0;
}

Upvotes: 0

Views: 89

Answers (1)

Pixelchemist
Pixelchemist

Reputation: 24946

Your class template BuiderType has a non type template parameter of type BuildersType and a pack of type template parameters named Args but your specialization has two non type template parameters FILENAME and CLASSNAME (where you use non of them to actually specialize BuiderType). In the line where you declare/define aBuilder you use a set of template parameters that is incompatible to the declaration of template<BuildersType, class ... Args> class BuiderType; because here you do not have any non type template parameters besides the first one.

This snippet has the same behaviour:

template<class ... Args> class A;

// this specialization has a template parameter that 
// 1. cannot and
// 2. will not be used in the parameter list for A
template<int I> class A<int> { };

int main()
{

  A<int> a; // error: A is an incomplete type
  A<2> b;   // error: '2' is not a type but 
            // A template expects type parameters

  return 0;
}

Upvotes: 2

Related Questions