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?
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.
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.
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).
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With