【发布时间】:2014-05-18 08:11:50
【问题描述】:
我希望在编译时通过模板参数切换默认构造函数的定义。我可以让它为转换构造函数编译 OK,但尝试使用该方法使默认构造函数被默认或不被默认 - 如果在特定模板参数的情况下,结果类可能是 POD,则很有用,但在另一种情况下,它不能 - 但这样做时我得到一个编译器错误。没有专门的模板和复制所有相同的代码,有没有办法做到这一点?这是我尝试的简化版本:
#include<type_traits> // for enable_if
template <bool MyParameter>
class Demonstration
{
public:
//trivial copy, move constructors/assignment, and trivial destructor
constexpr Demonstration(Demonstration const &) = default;
constexpr Demonstration(Demonstration &&) = default;
Demonstration & operator= (Demonstration const &) = default;
Demonstration & operator= (Demonstration &&) = default;
~Demonstration() = default;
// this one gives "error: a template cannot be defauled"
template <bool Dummy=MyParameter, typename std::enable_if< Dummy , bool >::type=true >
Demonstration() = default;
// ok
template <bool Dummy=MyParameter, typename std::enable_if< !Dummy , bool >::type=false >
Demonstration() : myValue(0) {}
// ok
template <bool Dummy=MyParameter, typename std::enable_if< Dummy , bool >::type=true >
explicit constexpr Demonstration(unsigned char toConvert)
: myValue ( toConvert )
{
}
// ok
template <bool Dummy=MyParameter, typename std::enable_if< !Dummy , bool >::type=false >
explicit constexpr Demonstration(unsigned char toConvert)
: myValue ( toConvert > 100 ? 0 : toConvert )
{
}
// a lot of functions that do not depend on parameter go here
protected:
private:
unsigned char myValue;
};
【问题讨论】:
-
即使编译了这个,
Demonstration<true>在技术上仍然不是 POD。 “普通类是具有默认构造函数的类,没有非普通默认构造函数,并且可以轻松复制。”Demonstration<true>有两个默认构造函数,一个很重要,尽管它永远不可能成为重载决议的可行函数。 -
CRTP 实现了重复的功能,并且 ctor 有两个专业?
-
您不能使用模板默认构造函数,因为您不能显式指定其模板参数。您只能使用允许编译器推断其模板参数的参数创建模板构造函数。您可以尝试使用模板静态函数来实现您想要的,该函数返回
Demonstration类的构造对象。 -
谢谢大家,这消除了我的困惑。 @Yakk:CRTP 确实看起来是一种基于模板参数将类设为 POD 或非 POD 的方法,而无需大量重复;如果您将其作为答案提交,我会接受。
-
@signifyingnothing 不,只是自我回答:我现在懒得写一篇好文章。一个糟糕的答案不值得写。