获取基数的更简单方法 Class

Simpler Method for Getting the Base Class

好的,所以我正在编写一个 answer here,它有更多的细节(和一个更好的选择。)但我意识到我已经制作了几个模板函数,它们有很多冗余。给定:

template<typename T>
struct Parent {};

struct Child : Parent<int> {};

我编写了以下模板函数来获取适当的 Parent 指针:

namespace details {
    template<typename T>
    Parent<T>* make_parent(Parent<T>* param) { return param; }
}

template<typename T>
auto make_parent(T& param) -> decltype(details::make_parent(&param)) { return details::make_parent(&param); }

里面好像重复了很多。但我不知道如何让它更干净。我可以将它组合成一个单一的功能而不是一场噩梦吗?

编辑:

我的意图是我能做到:

Child foo;
auto bar = make_parent(foo);

(与另一个答案中更简单的版本相反,我在其中传递了一个指针。)

所有这些都可以简化为

template<typename T>
Parent<T>* get_parent_ptr(Parent<T>& param) { return &param; }

这将为您提供指向从 Parent

派生的任何内容的 Parent 部分的指针

如果您还希望能够处理 const 对象,并防止获得指向临时对象的指针,不幸的是,您将不得不通过添加

来添加更多内容
template<typename T>
const Parent<T>* get_parent_ptr(const Parent<T>& param) { return &param; }

template<typename T>
Parent<T>* get_parent_ptr(Parent<T>&& param) = delete; // if you don't care about getting a pointer to a rvalue you can remove this

你可以看到所有这些都在使用这个 live example:

int main()
{
    Child c;
    auto cp = get_parent_ptr(c);
    const Child cc;
    auto ccp = get_parent_ptr(cc);
    //auto error = get_parent_ptr(Child{});
}

如果您取消注释 error 行,您将收到错误消息,提示您正在尝试使用已删除的函数。