Я пытаюсь использовать CRTP с производными классами, которые сами по себе шаблонизируются и сталкиваются с ошибками компилятора, которые я не знаю, как исправить.
Есть ли способ сделать то, что я хочу?
Код здесь.
#include <iostream>
// Parent class to use in CRTP
template <typename T>
class Singleton {
public:
static T& getInstance() {
Protector p;
static T instance(p);
return instance;
}
// Singleton pattern - no copying!
Singleton(const Singleton&) = delete;
Singleton(Singleton&&) = delete;
const Singleton& operator=(const Singleton&) = delete;
Singleton& operator=(Singleton&&) = delete;
protected: // so only derived classes can construct Singletons
Singleton() = default;
struct Protector {}; // avoids having to make Singleton a friend of descendents.
virtual ~Singleton() = default;
};
// Simple example of using the CRTP, this one compiles and runs as expected
class Counter final : public Singleton<Counter> {
private:
int _counter;
public:
Counter (Protector) : _counter(0) {std::cout << "Counter Constructor" << std::endl;}
~Counter () {std::cout << "Counter Destructor" << std::endl;}
int inc() {return ++_counter;}
int dec() {return --_counter;}
const int operator()() const {return _counter;}
};
// More complex example of using the CRTP. It generates compiler errors
template <typename T>
class TCounter final : public Singleton<TCounter<T>> {
private:
T _counter;
public:
TCounter (Protector) : _counter(0) {std::cout << "TCounter Constructor" << std::endl;}
~TCounter() {std::cout << "TCounter Destructor" << std::endl;}
T inc() {return ++_counter;}
T dec() {return --_counter;}
const T operator()() const {return _counter;}
};
int main () {
using namespace std;
Counter& ctr = Counter::getInstance();
cout << ctr() << ", " << ctr.inc() << ", " << ctr.dec() << endl;
using FCounter = TCounter<float>;
FCounter& fctr = FCounter::getInstance();
cout << fctr() << ", " << fctr.inc() << ", " << fctr.dec() << endl;
return 0;
}
вывод компилятора здесь
$ g++ src/goof.cpp -o goof
src/goof.cpp:45:22: error: function definition does not declare parameters
TCounter (Protector) : _counter(0) {std::cout << "TCounter Constructor" << std::endl;}
^
src/goof.cpp: In instantiation of ‘static T& Singleton<T>::getInstance() [with T = TCounter<float>]’:
src/goof.cpp:58:29: required from here
src/goof.cpp:10:12: error: no matching function for call to ‘TCounter<float>::TCounter(Singleton<TCounter<float> >::Protector&)’
static T instance(p);
^~~~~~~~
src/goof.cpp:41:7: note: candidate: ‘TCounter<float>::TCounter()’
class TCounter final : public Singleton<TCounter<T>> {
^~~~~~~~
src/goof.cpp:41:7: note: candidate expects 0 arguments, 1 provided
Вещи, которые я не понимаю:
- почему компилятор считает, чтокандидат конструктор принимает нулевые аргументы? (строка 41)
- он жалуется, что я не предоставляю параметр (строка 45), но когда я это делаю, он выдает другую ошибку - ожидая ')' после Protector.
Заранее спасибо за вашу помощь.