简体   繁体   English

模板化默认构造函数

[英]Templated Defaulted default constructor

I would like to have the definition of the default constructor be switched at compile time by a template parameter. 我想通过模板参数在编译时切换默认构造函数的定义。 I can get this to compile OK for a conversion constructor, but trying to use that method for a default constructor to be defaulted or not--useful if in the case of particular template parameter, the resulting class could be POD, but in another case, it could not--but I get a compiler error when doing so. 我可以让它为转换构造函数编译OK,但尝试使用该方法默认构造函数是否默认 - 如果在特定模板参数的情况下,生成的类可能是POD,但在另一种情况下,它不能 - 但这样做时我得到编译器错误。 Short of specializing the template and duplicating all the code that's the same, is there a way to do this? 如果没有专门化模板并复制所有相同的代码,有没有办法做到这一点? Here's a simplified version of what I was trying: 这是我尝试的简化版本:

#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;

};

GCC complains of your template: 海湾合作委员会抱怨你的模板:

error: a template cannot be defaulted

and Clang complains: 和Clang抱怨:

error: only special member functions may be defaulted.

That seems fair enough. 这看起来很公平。 A member function template is not a member function, let alone a special one. 成员函数模板不是成员函数,更不用说特殊函数了。

You would like Demonstration<bool P> to be POD when P is true and otherwise not necessarily so. P为真时,你希望Demonstration<bool P>为POD,否则不一定如此。

A possible solution is to delegate the parameterization of POD-ness entirely to specializations of a base template base<bool P> and have Demonstration<P> inherit base<P> . 一种可能的解决方案是将POD-ness的参数化完全委托给基本模板base<bool P>并让Demonstration<P>继承base<P> Here is an illustration: 这是一个例子:

#include<type_traits>

template<bool Param = true>
struct base // is POD 
{
    base() = default;
    explicit constexpr base(unsigned char ch)
    : _val(ch){}
    unsigned char _val;
};

template<>
struct base<false> // is not POD
{
    base() = default;
    explicit constexpr base(unsigned char ch)
    : _val(ch > 100 ? 0 : ch){}
    unsigned char _val = 0;
};


template <bool MyParameter>
class Demonstration : private base<MyParameter>
{   
public:

    Demonstration() = default;
    //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;

    explicit constexpr Demonstration(unsigned char toConvert)
    : base<MyParameter>(toConvert)
    {
    }

    char myValue() const {
        return base<MyParameter>::_val;
    }
};


#include <iostream>

using namespace std;

int main()
{
    cout << "is_pod<base<true>>::value = " 
        << is_pod<Demonstration<true>>::value << endl;
    cout << "is_pod<base<false>>::value = " 
        << is_pod<Demonstration<false>>::value << endl;
    cout << "is_pod<Demonstration<true>>::value = " 
        << is_pod<Demonstration<true>>::value << endl;
    cout << "is_pod<Demonstration<false>>::value = " 
        << is_pod<Demonstration<false>>::value << endl;
    Demonstration<true> d_true(1);
    Demonstration<false> d_false(101);
    std::cout << "(int)Demonstration<true>(1).myValue() = " 
        << (int)d_true.myValue() << endl;
    std::cout << "(int)Demonstration<false>(101).myValue() = " 
        << (int)d_false.myValue() << endl;
    return 0;
}

Now Demonstration<P> is POD just in case base<P> is POD. 现在Demonstration<P>是POD,以防万一base<P>是POD。 The program outputs: 该方案产出:

is_pod<base<true>>::value = 1
is_pod<base<false>>::value = 0
is_pod<Demonstration<true>>::value = 1
is_pod<Demonstration<false>>::value = 0
(int)Demonstration<true>(1).myValue() = 1
(int)Demonstration<false>(101).myValue() = 0

Built with GCC 4.8.2 and clang 3.3 使用GCC 4.8.2和clang 3.3构建

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 显式默认默认构造函数和聚合 - Explicit defaulted default constructor and aggregates 具有默认模板类型的默认构造函数的类型推导 - Type deduction for default constructor with defaulted template type 默认情况下是默认构造函数/赋值noexcept / constexpr吗? - Is a defaulted constructor/assignment noexcept/constexpr by default? 默认的默认构造函数触发 -Werror=effc - Defaulted default constructor triggers -Werror=effc 默认的默认构造函数是否将变量初始化为零? - Does the defaulted default constructor initialize variables to zero? 默认的默认构造函数,为什么它不是用户提供的默认构造函数? - A defaulted default constructor, why is it not a user-provided default constructor? gcc 4.8.2在此默认默认构造函数中调用复制构造函数时是否正确? - Is gcc 4.8.2 correct in invoking the copy constructor in this defaulted default constructor? 具有类内初始化的默认默认构造函数的行为是什么? - What is the behavior of a defaulted default constructor with in-class initialization? 为什么为联合或类似联合的 class 删除默认的默认构造函数? - Why is the defaulted default constructor deleted for a union or union-like class? 使用默认的默认构造函数进行C ++ 11值初始化 - C++11 value-initialization with defaulted default constructor
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM