我尝试使用模板元编程实现元组,但是我遇到了索引函数get
的问题。 Tuple
类型的实现是这样的:
template<typename A, typename... B>
class Tuple : Tuple<B...> {
private:
A val;
public:
using Base = Tuple<B...>;
Base* base() {
return static_cast<Base*>(this);
}
const Base* base() const {
return static_cast<const Base*>(this);
}
Tuple(A a, B... b): Base(b...), val(a) { }
A first() {
return val;
}
};
template<class A>
class Tuple<A> {
private:
A val;
public:
Tuple(A a): val{a} {}
A first() {
return val;
}
};
get
结构的实现是:
template<int N, class... A>
struct get {
select<N,A...> operator()(Tuple<A...> t) {
return get<N-1>()(t.base());
}
};
template<class R, class... A>
struct get<0> {
R operator()(Tuple<R, A...> t) {
return t.first();
}
};
这是编译器给我的错误:
tuple.cpp:53:8: error: partial specialization of 'get' does not use any of its template parameters
struct get<0> {
^
1 error generated.
为什么我收到此错误?我该如何纠正?
注意:select<N,A...>
是一个类型函数,它从A
选择第N个索引处的类型。
答案 0 :(得分:1)
也许您必须按照以下方式对get
进行部分专业化
template<class R, class... A>
struct get<0, R, A...> {
R operator()(Tuple<R, A...> t) {
return t.first();
}
};
我的意思是...... get<0, R, A...>
,而不是get<0>
但你还要修改主get
以使用正确的类型列表调用以下调用,所以
template<int N, typename A0, typename ... As>
struct get {
auto operator()(Tuple<A0, As...> t) {
return get<N-1, As...>()(t.base());
}
};
否则,您还可以要求将类型管理设置为operator()
的模板版本,并仅保留int N
的{{1}}值
get
从C ++ 14开始,您可以避免使用template <int N>
struct get
{
template <typename Tpl>
auto operator() (Tpl t)
-> decltype( get<N-1>()(t.base()) )
{ return get<N-1>()(t.base()); }
};
template<>
struct get<0>
{
template <typename Tpl>
auto operator() (Tpl t)
-> decltype ( t.first() )
{ return t.first(); }
};
部分。
非主题建议:避免使用可能与decltype()
命名空间名称冲突的名称。
可能std
和myGet
而不是myTuple
和get
。
否则,您可以将所有内容放入个人命名空间(Tuple
和myNs::get
。
答案 1 :(得分:1)
您的get
主要模板是:
template<int N, class... A>
struct get{ ... };
您get
的部分专业化是:
template<class R, class... A>
struct get<0>{ ... };
专业化是接收单个模板参数,即:0
,但上面的主模板有两个模板参数:
N
。A
。此外,如何推断出R
?
将get
专门化为:
template<class R, class... A>
struct get<0, R, A...>{ ... };
将使R
成为可能:它将被推导为传递的可变参数的第一个元素的类型。例如,在:
get<0, int, float, double> foo;
R
将推断为int
。