簡體   English   中英

模板化默認構造函數

[英]Templated Defaulted default constructor

我想通過模板參數在編譯時切換默認構造函數的定義。 我可以讓它為轉換構造函數編譯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;

};

海灣合作委員會抱怨你的模板:

error: a template cannot be defaulted

和Clang抱怨:

error: only special member functions may be defaulted.

這看起來很公平。 成員函數模板不是成員函數,更不用說特殊函數了。

P為真時,你希望Demonstration<bool P>為POD,否則不一定如此。

一種可能的解決方案是將POD-ness的參數化完全委托給基本模板base<bool P>並讓Demonstration<P>繼承base<P> 這是一個例子:

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

現在Demonstration<P>是POD,以防萬一base<P>是POD。 該方案產出:

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

使用GCC 4.8.2和clang 3.3構建

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM