繁体   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