只接受某类继承人的模板函数 在C++中,我有一些类妈妈< /代码>。我知道我可以创建一个接受任何类的模板函数,如: template <class T> void Iacceptanything(T x) { // Do something }
这可能吗?如果只接受某类继承人的模板函数 在C++中,我有一些类妈妈< /代码>。我知道我可以创建一个接受任何类的模板函数,如: template <class T> void Iacceptanything(T x) { // Do something },c++,templates,inheritance,C++,Templates,Inheritance,这可能吗?如果和std::是的基础,则使用std::enable #include <type_traits> #include <iostream> class Base { }; class Derived : public Base { }; class NotDerived { }; // If the return type of foo() is not void, add where indicated. template <typename T&
和std::是的基础,则使用std::enable
#include <type_traits>
#include <iostream>
class Base { };
class Derived : public Base { };
class NotDerived { };
// If the return type of foo() is not void, add where indicated.
template <typename T>
typename std::enable_if<std::is_base_of<Base, T>::value /*, some_type*/>::type
foo(T) {
std::cout << "Derived from Base." << std::endl;
}
// If the return type of foo() is not void, add where indicated.
template <typename T>
typename std::enable_if<!std::is_base_of<Base, T>::value /*, some_type*/>::type
foo(T) {
std::cout << "Not derived from Base." << std::endl;
}
int
main() {
Derived d;
NotDerived nd;
foo(d);
foo(nd);
}
#包括
#包括
类基{};
派生类:公共基{};
类NotDerived{};
//如果foo()的返回类型不是void,请在指定的位置添加。
模板
typename std::enable_if::type
傅(T){
std::cout使用std::enable\u如果和std::是的基础,如下所示:
template <typename T, typename = enable_if<is_base_of<mom, T>::value>::type>
void Iacceptonlysonsofmom(T x)
{
}
模板
void iaceptonlysonsofmom(tx)
{
}
如果不能使用C++11
,可以使用Boost的enable_If_C
和is_base_of
实现同样的功能。在上述代码中,您需要将enable_If
替换为enable_If_C
,并确保使用适当的名称空间。正如其他人建议的那样,您可以使用enable_If
但它也可能有问题。它在编译器中可能很脆弱,如果处理不当,可能会导致ODR出现问题,可能会与从其他作用域(ADL)中拉入的函数发生冲突,并且可能不是最佳选择
您确实有两种选择,它们不那么易变,可能使代码更易于理解和维护。一种选择(如注释中所述)是使用和。这是目前为止(IMHO)最简单的解决方案。这种方法允许您维护函数的单个实现,并在类型不是基Mom
或其派生类型时强制编译时失败
#include <type_traits>
struct Mom { };
struct Child : Mom { };
struct Uncle { };
template <typename T>
void AcceptOnlyMomAndChildren(T)
{
static_assert(std::is_base_of<Mom, T>::value, "Not derived from Base.");
}
int main()
{
Child child;
Uncle uncle;
AcceptOnlyMomAndChildren(child);
AcceptOnlyMomAndChildren(uncle); // Fails
}
在上面的示例中,用于指定附加参数的类型,以确定调用Func
的哪个实现。如有必要,您可以用自己的类型特征方案替换它以支持附加实现。您可以使用std::enable\u if
或static\u assert()
对于这一点,我建议不要限制模板参数;如果您使用依赖于mom
的某些功能,那么模板将无法与其他对象实例化(除非它们提供兼容的接口——如果它们提供了兼容的接口,那么为什么会对您产生任何影响?),但如果不这样做,则没有理由将其限制为仅在mom
对象上工作。您可以删除std::enable_if
的显式第二个参数,因为它默认为void
#include <type_traits>
struct Mom { };
struct Child : Mom { };
struct Uncle { };
template <typename T>
void AcceptOnlyMomAndChildren(T)
{
static_assert(std::is_base_of<Mom, T>::value, "Not derived from Base.");
}
int main()
{
Child child;
Uncle uncle;
AcceptOnlyMomAndChildren(child);
AcceptOnlyMomAndChildren(uncle); // Fails
}
#include <type_traits>
#include <iostream>
struct Mom { };
struct Child : Mom { };
struct Uncle { };
template <typename T>
void Func(T&, std::true_type)
{
std::cout << "Derived from Base." << std::endl;
}
template <typename T>
void Func(T&, std::false_type)
{
std::cout << "Not derived from Base." << std::endl;
}
template <typename T>
void Func(T& arg)
{
Func(
arg,
typename std::conditional<
std::is_base_of<Mom, T>::value,
std::true_type, std::false_type>::type());
}
int main()
{
Child child;
Uncle uncle;
Func(child);
Func(uncle);
}