【发布时间】:2017-05-04 10:51:23
【问题描述】:
考虑下面的代码:
#include <type_traits>
#include <iostream>
struct B {
virtual const char* whoami() const { return "I am a B!\n"; };
};
struct D : B {
const char* whoami() const override { return "I am a D!\n"; };
};
void foo_impl( B*(*pf)() )
{
B* b = pf();
std::cout << b->whoami();
}
template <class C>
auto foo( C*(*pf)() ) -> std::enable_if_t<std::is_base_of<B, C>::value> {
foo_impl(reinterpret_cast<B*(*)()>(pf));
}
D *bar() {
static D d_; // kludge to work around dangling pointer problem.
// Unrelated to the actual question
return &d_;
}
int main() {
foo(bar); // prints "I am a D!" on gcc 5.1
return 0;
}
函数指针当然不能按照标准强制,也许没有必要(我们总是可以只返回一个B*),但请幽默。据我所知,没有可能违反 LSP,所以如果可能的话,可以使用返回 D* 的函数以完全不透明的方式代替返回 B* 的函数。
薄foo 模板执行我希望编译器执行的静态类型检查,然后将类型信息抛到脑后。在这一点上,我知道除非我转换回原始指针类型,否则行为是未定义的(C++11 §5.2.10/6)。
因此我的问题是:
是否存在与标准无关的实际原因会导致上述代码失败?或者有没有其他的标准参考,可以缓解上面代码中UB的不愉快?
【问题讨论】:
标签: c++ undefined-behavior type-coercion