gpt4 book ai didi

c++ - 是否可以将 CRTP 与本身模板化的派生类一起使用?

转载 作者:行者123 更新时间:2023-11-28 01:16:01 25 4
gpt4 key购买 nike

我正在尝试将 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 之后有一个“)”。

预先感谢您的帮助。

最佳答案

您需要做的就是用手轻轻地引导编译器告诉它如何解析Protector

template <typename T>
class TCounter final : public Singleton<TCounter<T>> {
public:
using Protector = typename Singleton<TCounter<T>>::Protector;
};

关于c++ - 是否可以将 CRTP 与本身模板化的派生类一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58697483/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com