C++ 非类型的模板专门化

C++ 非类型的模板专门化,c++,templates,template-meta-programming,template-specialization,C++,Templates,Template Meta Programming,Template Specialization,考虑到我有一个简单的类模板: template <typename T> class foo { T t; }; 使用上面显示的类模板,而 foo<20> my_other_foo; foo my\u other\u foo; 使用不同的模板专用化?这是可能的吗?如果是,模板专用化代码是什么样子的 #include <type_traits> #include <iostream> template <typename T&g

考虑到我有一个简单的类模板:

template <typename T>
class foo
{
    T t;
};
使用上面显示的类模板,而

foo<20> my_other_foo;
foo my\u other\u foo;
使用不同的模板专用化?这是可能的吗?如果是,模板专用化代码是什么样子的
#include <type_traits>
#include <iostream>

template <typename T>
struct foo
{
    foo(T x) : t(x) {};

    T t;
};

// specialise for integral constant
template<class T, T N>
struct foo<std::integral_constant<T, N>>
{
    // same interface
    static constexpr T t = N;
};

// test
int main()
{
    auto foo1 = foo<float>(10.0);
    auto foo2 = foo<std::integral_constant<int, 20>>();

    std::cout << foo1.t << std::endl;
    std::cout << foo2.t << std::endl;
}
#包括 模板 结构foo { foo(tx):T(x){}; T; }; //专门研究积分常数 模板 结构foo { //同一接口 静态常数T=N; }; //试验 int main() { 自动foo1=foo(10.0); 自动foo2=foo(); 标准::cout 这是可能的吗?如果是,部分专门化代码是什么样子的

#include <type_traits>
#include <iostream>

template <typename T>
struct foo
{
    foo(T x) : t(x) {};

    T t;
};

// specialise for integral constant
template<class T, T N>
struct foo<std::integral_constant<T, N>>
{
    // same interface
    static constexpr T t = N;
};

// test
int main()
{
    auto foo1 = foo<float>(10.0);
    auto foo2 = foo<std::integral_constant<int, 20>>();

    std::cout << foo1.t << std::endl;
    std::cout << foo2.t << std::endl;
}
正如你所希望的,不,这是不可能的

但是,如果您可以使用C++17,您可以做几乎相反的事情:接收一个
auto
值(
T
成为该值的
declval()

此解决方案的问题是,您不能使用
foo
,因为
float
值不能是模板非类型参数(例如,您不能编写
foo

添加具有默认值(第一个参数的类型)的第二个模板类型参数可以大致绕过此问题

但是现在您可以调用
bar
作为旧
foo

下面是一个完整的编译(显然是C++17)示例

#包括
模板
结构foo
{
使用T=decltype(Val);
T{Val};//或decltype(Val)T{Val};
静态constexpr bool是专用的{false};
};
模板
结构foo
{
静态constexpr bool是专用的{true};
};
模板
结构条
{
T{Val};
静态constexpr bool是专用的{false};
};
模板
结构条
{
静态constexpr bool是专用的{true};
};
int main()
{

std::cout谢谢你的回答,但是我想使用foo foo_u;而不是:foo foo_uu;这也可能吗?@aart不,不是。
20
不是一个类型名。你写了“部分专门化”,但你所有的例子都是关于完全专门化的。
template <auto Val>
struct foo
 {
   using T = decltype(Val);

   T t { Val }; // or also decltype(Val) t {Val};

   static constexpr bool isSpecialized { false };
 };
template <>
struct foo<20>
 {
   static constexpr bool isSpecialized { true };
 };
template <auto Val, typename T = decltype(Val)>
struct bar
 {
   T t { Val };

   static constexpr bool isSpecialized { false };
 };
template <>
struct bar<20>
 {
   static constexpr bool isSpecialized { true };
 };
#include <iostream>

template <auto Val>
struct foo
 {
   using T = decltype(Val);

   T t { Val }; // or also decltype(Val) t {Val};

   static constexpr bool isSpecialized { false };
 };

template <>
struct foo<20>
 {
   static constexpr bool isSpecialized { true };
 };

template <auto Val, typename T = decltype(Val)>
struct bar
 {
   T t { Val };

   static constexpr bool isSpecialized { false };
 };

template <>
struct bar<20>
 {
   static constexpr bool isSpecialized { true };
 };

int main ()
 {
   std::cout << foo<0>::isSpecialized << std::endl;   // print 0
   std::cout << foo<20>::isSpecialized << std::endl;  // print 1
   std::cout << foo<20L>::isSpecialized << std::endl; // print 0

   std::cout << bar<0>::isSpecialized << std::endl;         // print 0
   std::cout << bar<20>::isSpecialized << std::endl;        // print 1
   std::cout << bar<20L>::isSpecialized << std::endl;       // print 0
   std::cout << bar<20, float>::isSpecialized << std::endl; // print 0

 }