好,所以我正在准备一个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(¶m)) { return details::make_parent(¶m); }
那里似乎有很多重复。但是我不知道如何使它更清洁。我可以将其合并为一个功能,而不会像噩梦吗?
编辑:
我的意图是我可以做到:
Child foo;
auto bar = make_parent(foo);
(与另一个答案中的简单版本相反,我在其中传递了一个指针。)
答案 0 :(得分:3)
所有这些都可以简化为
template<typename T>
Parent<T>* get_parent_ptr(Parent<T>& param) { return ¶m; }
这将为您提供从Parent
派生的任何内容的Parent
部分的指针
如果您还希望能够处理const
个对象,并防止获得指向临时对象的指针,那么不幸的是,您将不得不通过添加一些内容来添加
template<typename T>
const Parent<T>* get_parent_ptr(const Parent<T>& param) { return ¶m; }
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
行,则会出现错误并提示您尝试使用已删除的功能。