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
}