我正在尝试使用带有多个的模板将数据传递到函数上,但只使用第一个模板参数作为过滤器。像这样:
template <typename A, typename B>
class Component {
};
template <typename A>
class Context {
public:
void add(Component<A, void *> comp) {
}
}
typedef struct Foo { int x; } Foo;
typedef struct Bar { int y; } Bar;
Context<Foo> *context = new Context<Foo>();
Component<Foo, Bar> *comp = new Component<Foo, Bar>();
context->add(comp); // error
但是编译器抱怨它无法将Component<Foo, Bar>
转换为Component<Foo, void *>
。有没有办法实现这个目标?
答案 0 :(得分:1)
我认为你可能需要做的是改变'add'方法的签名:
template <typename A>
class Context
{
public:
template<class B>
void add(Component<A, B> comp)
{
}
};
但是,我不知道你问题的细节,所以这只是一个猜测。
答案 1 :(得分:0)
是的,将转换后的副本构造函数添加到Component
:
template<class U, class V>
Component(Component<U,V> const& other){
// ...
};
但是,相应的enable_if
SFINAE后卫仍然可以改进:
// <tr1/type_traits> for C++03
#include <type_traits> // for C++0x
template<class T, class U>
struct can_convert{
// std::tr1::... for C++03
static bool const value =
std::is_same<T,U>::value || std::is_convertible<T,U>::value;
};
template<class C1, class C2>
struct ice_and{
static bool const value = C1::value && C2::value;
}
// define for clarity and brevity
#define IF_CAN_CONVERT(A,B,U,V) \
typename std::enable_if<ice_and<can_convert<A,U>,can_convert<B,V> > >::type* = 0
template<class U, class V>
Component(Component<U,V> const& other, IF_CAN_CONVERT(A,B,U,V)){
// ...
};
答案 2 :(得分:0)
我正在尝试使用带有多个的模板将数据传递到函数上,但只使用第一个模板参数作为过滤器。 [...]但编译器抱怨它无法将Component转换为Component。有没有办法实现这个目标?
嗯,您的过滤器不起作用:您的add
函数只匹配第二个模板参数为void*
的组件,并且您提供Bar
。你还能期待什么呢?如果您还希望它处理其他“第二参数”,请删除过滤器,提供后备功能以使其匹配,或者进行某种转换。