【发布时间】:2016-07-23 06:59:21
【问题描述】:
考虑下面这段代码
#include <algorithm>
#include <iostream>
#include <memory>
#include <vector>
struct Base {
int x;
Base(int x) : x(x) {}
};
struct Derived : public Base {
int y, z;
Derived(int x) : Base(x), y(x + 1), z(x + 2) {}
};
void update(const std::vector<std::shared_ptr<const Base>>& elements) {
for (const auto elem : elements) {
std::cout << elem->x << "\n";
}
}
int main(int, char**) {
std::vector<std::shared_ptr<Derived>> elements(4);
{
int ctr = 0;
std::generate(begin(elements), end(elements), [&ctr]() { return std::make_shared<Derived>(++ctr); });
}
// update(elements); // note: candidate function not viable: no known conversion from 'vector<shared_ptr<Derived>>' to 'const vector<shared_ptr<const Base>>' for 1st argument
update(reinterpret_cast<std::vector<std::shared_ptr<const Base>>&>(elements)); // ok
return 0;
}
我的问题是使用reinterpret_cast 将std::vector<std::shared_ptr<Derived>> 转换为std::vector<std::shared_ptr<const Base>>& 是否可行并被标准接受。
我用clang-3.8和gcc-6.1用-fsanitize=undefined编译了代码,看起来没问题。但是,我似乎无法找到关于 cppreference 的正确解释。
当然,我可以轻松创建一个适当的函数,但它比单行 reinterpret_cast 更长,并且需要一个临时向量。
void update(const std::vector<std::shared_ptr<Derived>>& elements) {
std::vector<std::shared_ptr<const Base>> casted(elements.size());
std::copy(begin(elements), end(elements), begin(casted));
update(casted);
}
【问题讨论】:
-
你的代码是一个真实的用例,还是只是一个例子?如果这是一个真实的用例,恕我直言,这是对 reinterpret_cast 的错误使用。如果是示例,请提供您想要实现的真实用例
-
@wasthishelpful 或多或少是真实的用例;在单元测试期间提供数据库假对象
-
在您的示例中,您可以在主函数中使用 Base 的向量,或者在更新函数中使用模板。我想这在真实情况下是不可能的,但是从您发布的代码中我看不出为什么:)
标签: c++ reinterpret-cast class-hierarchy