简体   繁体   English

带有 std::is_base_of 的派生类的 C++ 模板函数

[英]C++ template function for derived class with std::is_base_of

I've got problem with creating function that for given type, if it's derived from other one do something and for all other cases do something other.我在为给定类型创建函数时遇到问题,如果它派生自其他类型,则执行某些操作,而对于所有其他情况,则执行其他操作。 My code:我的代码:

class BaseClass {};
class DerivedClass : public BaseClass {};

template <typename T>
void Function(typename std::enable_if<std::is_base_of<BaseClass, T>::value, T>::type && arg) {
    std::cout << "Proper";
}

template <typename T>
void Function(T && arg) {
    std::cout << "Improper";
}

void test() {
    Function(DerivedClass{});
}

For class DeriviedClass and other based on BaseClass I'd like to call function couting Proper , but it couts Improper .对于类DeriviedClass和其他基于BaseClass我想调用函数couts Proper ,但它couts Improper Any suggestions?有什么建议?

As mentioned in the comments to the question, SFINAE expressions won't work the way you did it.正如对问题的评论中提到的,SFINAE 表达式不会像你那样工作。
It should be instead something like this:它应该是这样的:

template <typename T>
typename std::enable_if<std::is_base_of<BaseClass, T>::value>::type
Function(T && arg) {
    std::cout << "Proper" << std::endl;
}

template <typename T>
typename std::enable_if<not std::is_base_of<BaseClass, T>::value>::type
Function(T && arg) {
    std::cout << "Improper" << std::endl;
}

SFINAE expressions will enable or disable Function depending on the fact that BaseClass is base of T . SFINAE 表达式将根据BaseClassT基础这一事实启用或禁用Function Return type is void in both cases, for it's the default type for std::enable_it if you don't define it.在这两种情况下,返回类型都是void ,因为如果您没有定义它,它就是std::enable_it的默认类型。
See it on coliru .coliru上看到它。

Other valid alternatives exist and some of them have been mentioned in other answers.存在其他有效的替代方案,其中一些已在其他答案中提到。

#include <typeinfo>
#include <iostream>

class BaseClass {};
class DerivedClass : public BaseClass {};
class OtherClass {};

template <typename T,typename = typename std::enable_if<std::is_base_of<BaseClass, T>::value, T>::type>
void Function(T && arg)
{
  std::cout << "Proper" << std::endl;
}

void Function(...)
{
  std::cout << "Improper"<< std::endl;
}

int main()
{
  Function(DerivedClass{});
  Function(BaseClass{});
  Function(OtherClass{});
}
template <typename T>
auto Function(T && arg) -> typename std::enable_if<std::is_base_of<BaseClass, T>::value>::type 
{
    std::cout << "Proper";
}

template <typename T>
auto Function(T && arg) -> typename std::enable_if<!std::is_base_of<BaseClass, T>::value>::type 
{
    std::cout << "Improper";
}

wandbox example 魔杖盒示例

C++11+ : C++11+:

#include <type_traits> // for is_base_of<>

class Base {};
class Derived : public Base {};

class NotDerived {};

template<typename Class>
void foo(const Class& cls)
{
  static_assert(is_base_of<Base, Class>::value, "Class doesn't inherit from Base!");
  // The codes...
}

int main()
{
  foo(Derived()); // OK!
  foo(NotDerived()); // Error!

  return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM