[Question] 类型推导在继承关系中的使用

2017-02-28 22:39:02 +08:00
 pagict

定义一个函数,当任何子类传入时,返回对应 runtime 的 vector<actual_class>. 如

some_type function(const Base& obj)  {
    // doing something
    return vector<Base>();
}

当实参为 Base 的子类 Derive时,如何推导返回 vector<Derive>? 尝试了 decltype(obj),对应类型是 Derive&,而在 vector 中是无法使用 reference 的。 而如果使用

std::remove_reference<decltype(obj)>::type

甚至

std::remove_const<std::remove_reference<decltype(obj)>::type>::type

,得到的都是 Base 类型。

如果把引用改成用指针,或者智能指针,应该是可破的。但是如果要坚持使用引用,求问有没有什么方法?

2056 次点击
所在节点    C
8 条回复
ryd994
2017-03-01 00:07:15 +08:00
这恐怕不能靠推导
用 template 吧
snnn
2017-03-01 08:29:37 +08:00
不可能。做不到。
你把这个函数改成模板函数就行了。
htfy96
2017-03-01 08:50:31 +08:00
template<typename DeriveT, typename = enable_if_t<is_base_of_v<BaseT, DeriveT>>>
foo bar(const DeriveT&)

大概是这样?
pagict
2017-03-01 09:49:18 +08:00
上面 3 位
@ryd994
@snnn
@htfy96
都推荐用模板,我思考了一下,应该有两种实现。

template<typename T>
vector<T> function(const T&) throws{
if (!is_base_of<Base, T>::value) throw exception;
// do something
return vector<T>();
}

第二种

template <typename T, typename = enable_if<is_base_of<Base, T>::value>::type>
vector<T> function(const T&) {
// do something
return vector<T>();
}

似乎第二种更好?
htfy96
2017-03-01 10:07:30 +08:00
@pagict 第一种 C++11 后可以改成 static_assert 但用模板前最好再仔细考虑下设计
pagict
2017-03-01 10:28:06 +08:00
@htfy96 static_assert 是编译时的,这里应该用运行时检查吧
htfy96
2017-03-01 10:50:35 +08:00
@pagict 不用啊 这里完全可以编译期确定
noli
2017-03-17 18:33:17 +08:00
典型的多分派行为,不想用模版的话可以考虑 Visitor 模式。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/343915

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX