[英]Template specialization with non-type
Considering I have a simple class template: 考虑到我有一个简单的类模板:
template <typename T>
class foo
{
T t;
};
Is it possible to specialize foo
such that T
is not a type but a non-type value so that: 是否可以专门化foo
使得T
不是类型而是非类型值,因此:
foo<float> my_foo;
Uses the class template shown above, while 使用上面显示的类模板,而
foo<20> my_other_foo;
Uses a different template specialization? 使用不同的模板专业化? Is this possible, and if yes, what would the template specialization code look like? 这是可能的,如果是的话,模板专业化代码会是什么样的?
Is this possible, and if yes, what would the partial specialization code look like? 这是可能的,如果是的话,部分专业化代码会是什么样的?
As you exactly want, no: it's impossible. 正如你想要的那样,不,这是不可能的。
But, if you can use C++17, you can make almost the contrary: receiving an auto
value ( T
become the declval()
of the value) 但是,如果你可以使用C ++ 17,你可以做出几乎相反的declval()
:接收一个auto
值( T
成为值的declval()
)
template <auto Val>
struct foo
{
using T = decltype(Val);
T t { Val }; // or also decltype(Val) t {Val};
static constexpr bool isSpecialized { false };
};
you can specialize for 20
(where 20
is an int
; doesn't match (by example) 20L
or 20U
) 你可以专门为20
(其中20
是一个int
;不匹配(例如) 20L
或20U
)
template <>
struct foo<20>
{
static constexpr bool isSpecialized { true };
};
The problem of this solution is that you can't have foo<float>
because a float
value can't be a template not-type parameter (so you can't write foo<0.0f>
, by example). 这个解决方案的问题是你不能有foo<float>
因为float
值不能是模板not-type参数(所以你不能写foo<0.0f>
,例如)。
You can roughly bypass this problem adding a second template type parameter with a default value (the type of the first parameter) 你可以大致绕过这个问题,添加第二个模板类型参数与默认值(第一个参数的类型)
template <auto Val, typename T = decltype(Val)>
struct bar
{
T t { Val };
static constexpr bool isSpecialized { false };
};
and the 20
specialization remain 而20
专业化仍然存在
template <>
struct bar<20>
{
static constexpr bool isSpecialized { true };
};
but now you can call bar<0, float>
as substitute of the old foo<float>
但现在你可以调用bar<0, float>
代替旧的foo<float>
The following is a full compiling (C++17, obviously) example 以下是完整的编译(显然是C ++ 17)示例
#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
}
#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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.