【发布时间】:2016-09-21 22:49:42
【问题描述】:
我有一个无法修改的外部库。该库声明了一个模板函数,由于某种原因返回 const 非引用对象:
template<class C>
const C foo();
我还有另一个无法修改的外部库。该库声明了一个不可复制的类,并且仅具有来自非常量对象的移动构造函数:
struct bar {
bar();
bar(const bar&)=delete;
bar(bar&&);
};
现在我需要使用foo<bar>。一个简单的用法:
bar buz() {
return foo<bar>();
}
失败了
main.cpp: In function 'bar buz()': main.cpp:13:21: error: use of deleted function 'bar::bar(const bar&)' return foo<bar>(); ^ main.cpp:8:5: note: declared here bar(const bar&)=delete; ^~~
这是有道理的,没有简单的解决方法可以编译代码。
但是,如果我添加一些更复杂的解决方法:
bar buz() {
return const_cast<bar&&>(std::move(foo<bar>()));
}
它编译并且整个代码按预期工作(不仅是上面的简化示例,还有我的真实代码)。
但是,它是安全的,还是我遇到了一些未定义的行为?有没有更好的解决方法?
我已阅读并了解有关从函数(1、2)返回 const 的问题,常见的答案似乎是在现代 C++ 中不鼓励返回 const 对象,但我的问题不是关于它,而是关于当外部库返回const 对象时如何解决这种情况。
【问题讨论】:
-
问题中隐含的假设是 API 在这里是错误的。你正在使用什么库?您要解决哪些问题需要您围绕 API 工作?
-
const_cast<bar>(foo<bar>())还不够吗?它仍然在返回语句中留下未命名的对象,所以移动语义应该启动 -
@Petr :/ 可悲的是,我会尝试
const_cast<bar&&>而不使用std::move,只是为了让它更简单。另外-您确定 foo 内部没有任何特定内容可以使const合理吗? -
不要依赖未定义的行为。如果需要,切换库
-
@Petr 好吧,我更喜欢保证工作的长代码,而不是将来可能会中断的短代码:)
标签: c++ c++11 constants move-semantics