【发布时间】:2017-05-12 03:14:19
【问题描述】:
我编写了一个类来促进类型擦除,它具有以下构造函数:
class Envelope {
public:
Envelope() {}
template<typename Runnable>
Envelope(Runnable runnable)
: m_runFunc(&Envelope::RunAndDeleteRunnable<Runnable>), m_runnable(new Runnable(runnable)) {
}
template<typename Runnable>
Envelope(Runnable * runnable)
: m_runFunc(&Envelope::RunRunnable<Runnable>), m_runnable(runnable) {
}
};
我想重写第一个非默认构造函数以获取引用而不是值(Runnable & runnable 而不是 Runnable runnable),但如果我这样做,那么使用非常量复制 Envelope 就像这样
Envelope next(...);
Envelope otherNext(next);
调用该构造函数而不是复制构造函数,我得到堆栈溢出。
我想我可以防止在 Runnable == Envelope 和 std::enable_if 这样的情况下调用该构造函数
template<typename Runnable = typename std::enable_if<std::negate<std::is_same<Runnable, Nova::Envelope>>::value, Runnable>::type>
Envelope(Runnable & runnable)
: m_runFunc(&Envelope::RunAndDeleteRunnable<Runnable>), m_runnable(new Runnable(runnable)) {
}
它编译得很好(尽管它在 Visual Studio 2015 中触发了一些智能感知错误,这有点烦人),但它并不能阻止使用非 const Envelopes 调用该构造函数并触发堆栈溢出。
我不完全确定我在这里做错了什么。
【问题讨论】:
-
std::negate是一元-,而不是一元!。这意味着它实际上并没有做任何事情,因为它正在将 1 更改为 -1(这仍然是真实的),并且不会更改为零。你的意思可能是std::enable_if<!std::is_same<Runnable, Nova::Envelope>::value, Runnable>::type> -
@cdhowie 这可能值得回答,IMO。
标签: c++ c++11 templates template-meta-programming typetraits