#include <stdlib.h>
#include <stdint.h>
#include <vector>
struct MyClass1 {
virtual ~MyClass1() = default;
};
template <typename T>
struct MyClass2 : public MyClass1 {};
template <class...C> class MyClass3 { //will be singleton class
public:
MyClass3()
{
make_classes<C...>(_class_vec);
}
private:
static const size_t _num_classes = sizeof...(C);
static uint8_t *_buf[_num_classes];
std::vector<MyClass1*> _class_vec;
void make_classes(std::vector<MyClass1*> &vec) {}
template <class First, class... Rest> void make_classes(std::vector<MyClass1*> &vec) {
static size_t count;
First* tmp = new (_buf[count++]) First;
vec.push_back(tmp);
make_classes<Rest...>(vec);
}
};
int main() {
auto foo = MyClass3<MyClass2<int>, MyClass2<char>>();
return 0;
}
我试图将一组可变参数模板参数传递给Class3的构造函数,并使用placement new将它们放在适当大小的池的单元格中,其第一维在编译时计算。然后使用基础对象的类型构造一个指向它们的指针向量(传递给Class3模板的派生对象使用单个变量类型进行模板化。)
这编译好了,但是当我在main中创建一个Class3类型的对象时,我得到以下错误:
prog.cpp: In instantiation of 'void MyClass3<C>::make_classes(std::vector<MyClass1*>&) [with First = MyClass2<char>; Rest = {}; C = {MyClass2<int>, MyClass2<char>}]':
prog.cpp:32:29: required from 'void MyClass3<C>::make_classes(std::vector<MyClass1*>&) [with First = MyClass2<int>; Rest = {MyClass2<char>}; C = {MyClass2<int>, MyClass2<char>}]'
prog.cpp:17:29: required from 'MyClass3<C>::MyClass3() [with C = {MyClass2<int>, MyClass2<char>}]'
prog.cpp:38:57: required from here
prog.cpp:32:29: error: no matching function for call to 'MyClass3<MyClass2<int>, MyClass2<char> >::make_classes(std::vector<MyClass1*>&)'
make_classes<Rest...>(vec);
^
prog.cpp:27:55: note: candidate: template<class First, class ... Rest> void MyClass3<C>::make_classes(std::vector<MyClass1*>&) [with First = First; Rest = {Rest ...}; C = {MyClass2<int>, MyClass2<char>}]
template <class First, class... Rest> void make_classes(std::vector<MyClass1*> &vec) {
^
prog.cpp:27:55: note: template argument deduction/substitution failed:
prog.cpp:32:29: note: couldn't deduce template parameter 'First'
make_classes<Rest...>(vec);
使用可变参数模板实现此目的的正确方法是什么?请记住,我在嵌入式平台上工作,所以我的编译器兼容C ++ 11,但很多STL和Boost对我来说都不可用。
答案 0 :(得分:2)
编译错误是因为对make_classes
的最后一次递归调用是:
make_classes<>(vec);
当然,这与模板功能不匹配。
void make_classes(std::vector<MyClass1*> &vec) {}
这不是模板功能。之间有区别:
make_classes(vec);
和
make_classes<>(vec);
你可以尝试专门化模板功能,但是在整个模板类中,这会很快变得丑陋。
最简单的解决方案是将make_classes
()替换为:
template <class First> void make_1class(std::vector<MyClass1*> &vec)
{
static size_t count;
First* tmp = new (_buf[count++]) First;
vec.push_back(tmp);
}
template <typename OneClassLeft>
void make_classes(std::vector<MyClass1*> &vec)
{
make_1class<OneClassLeft>(vec);
}
template <class First, class Second, class ...Rest>
void make_classes(std::vector<MyClass1*> &vec)
{
make_1class<First>(vec);
make_classes<Second, Rest...>(vec);
}
答案 1 :(得分:2)
代码中的递归缺少基本情况,即具有空参数包的情况 非模板成员函数不参与游戏,因为您始终使用以下行明确地专门化模板成员函数:
make_classes<Rest...>(0, vec);
可能的解决方案是:
修改构造函数:
MyClass3()
{
make_classes<C...>(0, _class_vec);
}
更新make_classes
个功能:
template<typename... T>
std::enable_if_t<sizeof...(T)==0>
make_classes(int, std::vector<MyClass1*> &vec) {}
template <class First, class... Rest> void make_classes(char, std::vector<MyClass1*> &vec) {
static size_t count;
First* tmp = new (_buf[count++]) First;
vec.push_back(tmp);
make_classes<Rest...>(0, vec);
}
注意:除非您在某处定义_buf
,否则无论如何都不会编译。
答案 2 :(得分:1)
你有一个没有基本情况的递归调用。最后,您正在调用make_classes<>(vec);
,因为当您使用一种类型调用它时,First
吃掉了Rest...
并且template<class First>
为空。
你需要一些东西来处理这个基本案例Parameterized
,你应该做得很好。