簡體   English   中英

(部分)專門化依賴類型的非類型模板參數

[英](Partially) specializing a non-type template parameter of dependent type

也許我累了,但我堅持使用這個簡單的部分專業化,這不起作用,因為non-type template argument specializes a template parameter with dependent type 'T'

template <typename T, T N> struct X;
template <typename T>      struct X <T, 0>;

T(0)T{0}(T)0替換0沒有幫助。 那么這種專業化甚至可能嗎?

參見標准的 [temp.class.spec] 14.5.5/8 段:

對應於專門化的非類型參數的模板參數的類型不應依賴於專門化的參數。 [示例:

 template <class T, T t> struct C {}; template <class T> struct C<T, 1>; // error template< int X, int (*array_ptr)[X] > class A {}; int array[5]; template< int X > class A<X,&array> { }; // error

—結束示例]

編輯的答案:最簡單的解決方法是用類型一替換非類型模板參數:

#include <type_traits>

template <typename T, typename U>
struct X_;

template <typename T, T N>
struct X_<T, std::integral_constant<T, N>> {};

template <typename T>
struct X_<T, std::integral_constant<T, 0>> {};

template <typename T, T N>
struct X : X_<T, std::integral_constant<T, N>> {};

使用 Yakk 的解決方案的解決方案:

#include <iostream>
#include <type_traits>

template <typename T, T N, typename = void > 
struct X {
  static const bool isZero = false;
};

template <typename T, T N>
struct X < T, N, typename std::enable_if<N == 0>::type > {
  static const bool isZero = true;
};

int main(int argc, char* argv[]) {
    std::cout << X <int, 0>::isZero << std::endl;
    std::cout << X <int, 1>::isZero << std::endl;
    return 0;
}

現場演示

您可以在template參數列表的末尾添加一個typename=void參數,然后在專業化中使用std::enable_if_t< condition >瘋狂。

您需要在模板中傳遞一個整數值,如果類型 T 不是整數類型,則您的第一個和第二個模板都將不起作用。

您可以將 Traits 作為類型化模板參數傳遞以指定值 N:

#include <iostream>

// error: ‘double’ is not a valid type for a template non-type parameter
template <typename T, T N> struct X0;

// error: ‘double’ is not a valid type for a template non-type parameter
template <typename T, T N, int = 0> struct X1;



template <typename T, T N>
struct IntegralTraits {
    static constexpr T Value() { return N; }
};

template <typename T, typename Traits = void>
struct X2 {
    static constexpr T Value() { return Traits::Value(); }
};

template <typename T>
struct X2<T, void> {
    static constexpr T Value() { return T(); }
};


int main() {
    // error: ‘double’ is not a valid type for a template non-type parameter
    // X0<double, 0>();

    // error: ‘double’ is not a valid type for a template non-type parameter
    // X1<double, 0>();

    X2<int> a;
    X2<double, IntegralTraits<int, 1>> b;

    std::cout.precision(2);
    std::cout << std::fixed  <<  a.Value() << ", "<< b.Value() << '\n';
    return 0;
}

如果您限制自己使用整數類型,請選擇一個大的類型:

template <typename T, std::size_t N = 0> struct X {};

暫無
暫無

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

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