c++ - 重载函数模板和继承参数

标签 c++ templates inheritance

这段代码:

#include <iostream>

class A {};

class B : public A {};

class C {
public:
    template <typename T>
    void x(const T& t) {
        std::cout << "template" << std::endl;
    }

    void x(const A*& a) {
        std::cout << "a" << std::endl;
    }

    void x(const int& a) {
        std::cout << "int" << std::endl;
    }

    template <typename T>
    void y(T t) {
        std::cout << "template" << std::endl;
    }

    void y(A* a) {
        std::cout << "a" << std::endl;
    }

    void y(int a) {
        std::cout << "int" << std::endl;
    }

    template <typename T>
    void z(const T& t) {
        std::cout << "template" << std::endl;
    }
};

// Does not compile
// template <>
// void C::z(const A*& a) {
//  std::cout << "a" << std::endl;
// }

template <>
void C::z(const int& a) {
    std::cout << "int" << std::endl;
}

int main(int argc, char** argv) {
    C c;
    c.x(new A());
    c.x(new B());
    c.x(1);
    c.y(new A());
    c.y(new B());
    c.y(1);
    c.z(new A());
    c.z(new B());
    c.z(1);
}

打印:

template
template
int
a
template
int
template
template
int

我有以下问题:

  • 为什么 void C::z(const int& a) 编译但 void C::z(const A*& a) 不编译?

  • 问题的合理解决方案是什么?我需要一个模板化函数来一般地处理各种各样的参数,但是需要专门处理大量具有公共(public)基础的类。我需要一些方法来打印 a a int

编辑:感谢@AndyG 的建议,我能够用一些 type_traits 和下面的代码解决这个问题:

#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/remove_pointer.hpp>

#include <iostream>

class A {};

class B : public A {};

class C {
public:
    template <typename T>
    typename boost::disable_if<boost::is_base_of<A, typename boost::remove_pointer<T>::type>, void>::type x(const T& t) {
        std::cout << "template" << std::endl;
    }

    void x(A*const& a) {
        std::cout << "a" << std::endl;
    }

    void x(const int& a) {
        std::cout << "int" << std::endl;
    }
};

int main(int argc, char** argv) {
    C c;
    c.x(new A());
    c.x(new B());
    c.x(1);
}

最佳答案

答案是因为 const在指针类型上有点奇怪。

你要的是这个:

template <>
void C::z( A*const&  a) {
  std::cout << "a" << std::endl;
}

const需要从右到左阅读。自 z接受 T& , 当你想专攻 A*你需要放置 constA* 之后而不是在前面。

Demo

关于c++ - 重载函数模板和继承参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44370715/

相关文章:

c++ - 基类中的私有(private)静态成员

c++ - 为什么这会导致模棱两可的模板错误?

c++ - 创建一个编译时键到类型映射,通过调用可变参数函数来填充

Java非泛型方法隐藏具有交集类型的泛型方法

c++ - 如何在没有 Python 调试库的情况下在 Debug模式下使用 Cmake/Visual Studio 构建 OpenCV

c++ - 当参数是目录时,Ifstream open() 不设置错误位

c++ - 类构造函数引用自身添加到vector

c++ - C++ 中的规范化 XML

c++ - 防止调用模板化复制构造函数

c++ - 为什么不能在派生类的构造函数初始化列表中初始化基类的数据成员?