簡體   English   中英

帶有 enable_if 外部類原型的模板類構造函數定義

[英]template class constructor definition with enable_if outside class prototype

有一個問題與我之前的問題有些相關,它涉及模板類,它在一個方法上使用std::enable_if ,該方法在類原型中聲明,但實際實現是在外面完成的。

來源: 在類定義之外使用 enable_if 的函數實現

我想做類似的事情,但是使用類構造函數,我想用std::enable_if元函數定義外部模板類。

template <typename T>
using EnableIfArithmetic = typename std::enable_if<std::is_arithmetic<T>::value, void>::type;

template <typename NumericType>
class SomeClass {
public:
    // constructor definition
    template <typename = EnableIfArithmetic<NumericType>>
    SomeClass() {
        // do some stuff
    }
};

所需形式:

template <typename NumericType>
class SomeClass {
public:
     // constructor declaration
     template <typename = EnableIfArithmetic<NumericType>>
     SomeClass();
};

// constructor definition
template <typename NumericType>
template <typename = EnableIfArithmetic<NumericType>>
SomeClass<NumericType>::SomeClass() {
        // constructor implementation
}

但是如果沒有編譯錯誤,我就做對了。 我究竟做錯了什么?

模板參數的默認值不應在定義中重復。 例如:

template<typename N>
struct S {
    template<typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>>
    S(T);
};

template<typename N>
template<typename T, typename>
S<N>::S(T) { }

您使用 SFINAE 的方式不正確: EnableIfArithmetic應該取決於某種推導類型(在同一模板中)。 請參考這個問題 例如:

template<typename T = N, typename = EnableIfArithmetic<T>>
S() { }

否則,將發生硬故障:

錯誤:在“struct std::enable_if”中沒有名為“type”的類型

如果要禁用某些類型N的默認構造函數,也可以在構造函數中使用static_assert 但是,它不會對 SFINAE 友好。

template<typename N>
struct S1 {
public:
    template<typename T = N, typename = std::enable_if_t<std::is_arithmetic_v<T>>>
    S1() { }
};

template<typename N>
struct S2 {
public:
    S2() { static_assert(std::is_arithmetic_v<N>); }
};

static_assert(std::is_default_constructible_v<S1<int>>);
static_assert(!std::is_default_constructible_v<S1<void>>);

static_assert(std::is_default_constructible_v<S2<int>>);
static_assert(std::is_default_constructible_v<S2<void>>);

暫無
暫無

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

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