我遇到了一个C ++模板难题。我试图把它减少到最低限度,现在我甚至不确定我想做的事情是否可行。看一下下面的代码(在一些.h文件中)。
template<typename T>
class A
{
public:
template<typename S>
void f(S x);
};
class B1 { };
template<typename S>
class B2 { };
//This one works:
template<>
template<typename S>
void A<B1>::f(S x)
{
}
//This one does not work:
template<>
template<typename S>
void A<B2<S>>::f(S x)
{
}
在我的main
函数中,我有类似的东西:
//This one works:
A<B1> first;
first.f<int>(5);
//This one does not work:
A<B2<int>> second;
second.f<int>(5);
我得到的错误信息是因为第二部分是
error C3860: template argument list following class
template name must list parameters in the
order used in template parameter list
error C3855: 'A<T>': template parameter 'T' is
incompatible with the declaration
知道问题是什么吗?
为了使问题更具体,这是我的动力。我希望上面的函数f
具有T=std::tuple<T1, T2>
,T=std::tuple<T1, T2, T3>
和T=std::tuple<T1, T2, T3, T4>
的特化,其中tuple
中的类型仍未绑定。
答案 0 :(得分:4)
您正在尝试部分专门化成员函数模板。那是不可能的,我害怕......
答案 1 :(得分:4)
您的代码有两个问题。首先,第二个专业化是非法的,因为
template<> // parameters useable for the specialization of A you refer to
// since it is a function, no partial specialization is allowed.
template<typename S> // parameters for the function's parameters
void A<B2<S>> // S can not be used here!
::f(S x) // only here
{
}
如果我将其更改为
template<>
template<typename S>
void A<B2<int>>::f(S x)
{
}
它有效,现在第二个问题暴露出来了:
second.f<B2<int>>(5);
这将S
设置为B2<int>
,函数需要参数S x
- 但整数5
无法转换为该类型。将其更改为:
B2<int> x;
second.f<B2<int>>(x);
也可以。
请注意,这可能无法解决您尝试解决的问题,它只是解释了会发生什么。
考虑您的修改:我认为您尝试专注于T=std::tuple<...>
的事实已经指明了方向:T
是A
和的模板参数是你应该专攻的。也许是这样的:
template< typename T >
class F // used to implement f(), so you can specialize
// just F/f() instead of the whole class A
{
void f(T x) { /* default impl */ }
};
template< typename T1, typename T2 >
class F< std::tuple< T1, T2 > >
{
void f(T1 x, T2 y) { /* special impl */ }
};
template< typename T >
class A : public F< T >
{
// ...other stuff...
};
答案 2 :(得分:1)
如果您想将另一个模板传递给模板,则必须使用template template parameters,因此您的A&lt;&gt;模板看起来像这样:
template<typename T>
class A
{
public:
template<template <typename> class H, typename S>
void f(H<S> x);
};
现在您可以将模板传递给模板。
如果您的原始模板没有采用这样的参数类型,我认为您不能专注于模板模板参数。