C++ 指针类型的模板函数重载

标签 c++ template-meta-programming

我使用 std::type_index 对象作为状态类的唯一标识符(基本上,工厂函数中的键用于生成引用类型的新对象)。类的 ID、该类的对象以及指向该类对象的指针都应该相同。因此,我尝试这样做:

using stateid_t = std::type_index;
template<class T> inline stateid_t GetStateID() { return typeid(T); }
template<class T> inline stateid_t GetStateID(const T&) { return typeid(T); }
template<class T> inline stateid_t GetStateID(const T*) { return typeid(T); }

但是,第三个版本永远不会被像 GetStateID(this); 这样的东西调用,总是第二个版本,T 的类型被推导为“指向 T 的指针”。

认为我应该能够使用std::enable_if以某种方式做到这一点,但我似乎想不出任何有效的方法。

编辑

我主要想要的是一组满足的函数

struct A{};
A a;
const A b;
//fixed asserts based on comments
assert(GetStateID<A>() == GetStateID(a));
assert(GetStateID(a) == GetStateID(&a));
assert(GetStateID(a) == GetStateID(b));

//added some new constraints
struct X : public A{};
X x;
assert(GetStateID<A>() != GetStateID<X>());
assert(GetStateID(a) != GetStateID(x));

解释为什么没有选择指针重载的奖励积分。

最佳答案

大概您正在从非 const 调用这些函数成员函数。如果是这样的话 stateid_t GetStateID(const T*)需要隐式转换(从 U*const U*,其中 U 是类的类型),而 stateid_t GetStateID(const T&)不( U 将是 U* )。在 const 的背景下成员(member)功能您的this指针已经是 const U *它不需要隐式转换,应该调用 stateid_t GetStateID(const T*) .

删除那些 const应该解决问题。两者U*const U*更喜欢 stateid_t GetStateID(T*)超过stateid_t GetStateID(T&) .

但是,您似乎正在尝试实现已解决问题的解决方案。表达式typeid(std::remove_pointer_t<T>);应该已经生产出你想要的东西了。就您的代码而言,以下内容应该适合您:

using stateid_t = std::type_index;
template<class T> inline stateid_t GetStateID() { 
    return typeid(std::remove_pointer_t<T>);
}

编辑:为了完成您的界面要求,您可以添加一个函数模板来推导 T :

template<class T> inline stateid_t GetStateID(T&&) {
    return GetStateID<T>(); 
}

关于C++ 指针类型的模板函数重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54188129/

相关文章:

c++ - 如何导入libusb dll

c++ - OpenGL c++ - 出现不需要的黑色三角形

c++ - Nix Gradle dist - 无法为 Linux amd64 加载 native 库 'libnative-platform.so'

C++11 可变参数模板模板参数

c++ - 类型别名模板参数包

c++ - 比较对 int 和 unsigned 的引用时发出警告,但如果将 const(无引用)与 g++/msvc 进行比较则没有警告

java - JNA如何在Java中使用这个方法?

c++ - 强制表达式为 constexpr

c++ - 使用受限函数时的尾随返回类型问题

c++ - 仿函数参数和结果的任意类型转换