我得到一个编译器错误
../main.cpp: In function ‘int main()’:
../main.cpp:38:16: error: no matching function for call to ‘do_stuff(x&)’
../main.cpp:38:16: note: candidate is:
../main.cpp:30:6: note: template<class M> void do_stuff(M, typename a<M>::is_valid_type)
make: *** [main.o] Error 1以获取以下代码:
template<typename S>
class a
{
};
template<typename T>
class b
{
};
class x: public b<int>
{
};
template<typename T>
class a<b<T> >
{
public:
typedef void* is_valid_type;
};
template<typename M>
void do_stuff(M thing, typename a<M>::is_valid_type t = 0)
{
a<M> whatevs;
}
int main()
{
x my_x;
do_stuff(my_x);
}在这里,我想隐式地将x类型的对象强制转换为定义了a::is_valid_type的某个超类M(在本例中为b)。但这似乎行不通。我该怎么做呢?
(不使用任何c++-11构造)
发布于 2014-03-09 12:51:48
如果我正确理解了您的问题,编译器将不会使用模板参数x匹配b<int>的模板专门化,即使x继承自b<int>,因为对于编译器要选择的模板专门化,类型必须完全匹配。
相反,如果要确保模板参数是从某个基类派生的类的实例,则可以考虑如下内容:
template<typename TDerived, typename TBase>
struct AssertInheritedType
{
inline AssertInheritedType(void)
{
if (false)
{
TBase * p1 = static_cast<TDerived *>(0); // If compiler error here, TDerived* cannot be implicitly cast into TBase*
p1 = p1;
}
} // AssertInheritedType()
}; // struct AssertInheritedType要使用此功能,您需要执行以下操作:
template<typename M>
void do_stuff(M thing)
{
AssertInheritedType<M, b<int> >();
a<M> whatevs;
}如果参数不是从b<int>派生的,这将导致do_stuff()实例的编译失败。
发布于 2014-03-09 12:11:23
我认为这是不可能的。一个模板的两个不同的实例没有任何共同之处,它不像继承那样工作。
class x : public b<int>
{
};
class y : public b<float>
{
};这里的类x和y没有共同的祖先,因为b和b是完全不同的类。
编辑:您可以为b类提供祖先,它不是模板。我不知道专门化这个模板的其他方法,在C++11中它看起来像这样:
#include <type_traits>
class b_base
{
};
template<typename S,typename U = void>
class a;
template<typename T>
class b: public b_base
{
};
class x : public b<int>
{
};
class z
{
};
template<typename T>
class a<T,typename std::enable_if<std::is_base_of<b_base, T>::value>::type>
{
};
int main()
{
//this works
a<x> c1;
//this doesn't
a<z> c1;
}https://stackoverflow.com/questions/22278003
复制相似问题