Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template definition of non-template error

I want to use the CRTP pattern in combination with some locking mechanism for access syncing in multithreaded environment.

My code looks like this:

//-- CRTP base class with some sync/lock mechanism
template<typename T, typename SYNC>
struct Base {
  static std::unordered_map<int, std::string> s_map;
  static SYNC s_sync;
};

//-- derived class using CRTP
template<typename SYNC>
struct ProductX : public Base<ProductX<SYNC>, SYNC> {};

//-- static initialisation
template<typename SYNC>
std::unordered_map<int, std::string> Base<ProductX<SYNC>, SYNC>::s_map {
  { 1, "value_1" },
  { 2, "value_2" }
}

However I get

error: template definition of non-template std::unordered_map<int, std::basic_string<char> > Base<ProductX<SYNC>, SYNC>::s_map

when compiling.

The error is raised for the static s_map initialisation. Can someone point me what I'm doing wrong?

like image 279
Martin Pasko Avatar asked Jul 22 '15 07:07

Martin Pasko


People also ask

What is template explain with example?

A template is a simple yet very powerful tool in C++. The simple idea is to pass data type as a parameter so that we don't need to write the same code for different data types. For example, a software company may need to sort() for different data types.

What is the concept of template?

A template is a form, mold or pattern used as a guide to make something. Here are some examples of templates: Website design. Creating a document. Knitting a sweater.

What is a template in code?

Code Templates are reusable code snippets that allow you to quickly insert commonly used code fragments or surround given code fragment with a meaningful code block (example: try-catch statement).


2 Answers

You use Base<ProductX<SYNC>, SYNC> as the members specialization in the definition of s_map, so you actually need a corresponding partial specialization of Base (§14.5.5.3/1). In other words, you're trying to define a member of a non-existent partial specialization.

Try providing that specialization:

template<typename SYNC>
struct ProductX;

//-- CRTP base class with some sync/lock mechanism
template<typename T, typename SYNC>
struct Base {};
template<typename SYNC>
struct Base<ProductX<SYNC>, SYNC> {
  static std::unordered_map<int, std::string> s_map;
  static SYNC s_sync;
};

//-- derived class using CRTP
template<typename SYNC>
struct ProductX : public Base<ProductX<SYNC>, SYNC> {};

//-- static initialisation
template<typename SYNC>
std::unordered_map<int, std::string> Base<ProductX<SYNC>, SYNC>::s_map {
  { 1, "value_1" },
  { 2, "value_2" }
};

Demo.

like image 111
Columbo Avatar answered Sep 29 '22 18:09

Columbo


A simplified example.

template <class A, class B>
struct C
{
    static int x;
};

template <class A, class B> int C<A, B>::x = 0; // this works

However

template <class A> int C<A, double>::x = 0; // same error as yours

The latter definition belongs to a partial specialization of C which does not exists. Create one:

template <class A>
struct C<A, double>
{
    static int x;
};

template <class A> int C<A, double>::x = 1;

and all is well again.

like image 36
n. 1.8e9-where's-my-share m. Avatar answered Sep 29 '22 20:09

n. 1.8e9-where's-my-share m.