如何使用 type_traits 仅在特定类型上添加模板 class 的成员函数 | C++
How to add member function of template class only on specific types using type_traits | C++
template <typename T>
class A
{
template <std::enable_if_t<std::is_signed_v<T>, bool> = true>
constexpr value_type determinant()
{
}
}
我想仅当类型 T
是有符号类型时才实例化行列式函数
所以我尝试了这段代码,但是当类型 T
是无符号编译器时,编译器仍然尝试实例化行列式函数。
我不想针对每个签名类型专门化模板函数 T
。
我想使用 std::is_signed_v
类型特征来简化代码
使用 SFINAE,当测试的条件与方法本身的模板参数相关时,您可以 enable/disable class 的方法。无法测试 class.
的模板参数
您可以解决通过默认使用 class/struct 模板参数类型的方法模板参数传递的问题。
例如
#include <iostream>
#include <type_traits>
template <typename T>
struct foo
{
template <typename U = T,
std::enable_if_t<std::is_signed_v<U>, bool> = true>
constexpr std::size_t bar ()
{ return sizeof(T); }
};
int main()
{
foo<signed int> fs;
foo<unsigned int> fu;
fs.bar(); // compile
//fu.bar(); // compilation error
}
这个解决方案的问题是你可以“劫持”它解释一个模板参数
fu.bar(); // compilation error
fu.bar<int>(); // compile
为了避免劫持风险,您可以(其他解决方案也是可能的,但这是我的首选)在 U
之前添加一个非类型可变参数模板参数
// .......VVVVVVVV add this to avoid the hijacking problem
template <int ...,
typename U = T,
std::enable_if_t<std::is_signed_v<U>, bool> = true>
constexpr std::size_t bar ()
{ return sizeof(T); }
// ...
fu.bar(); // compilation error
fu.bar<int>(); // compilation error
fu.bar<1, 2, 3, int>(); // compilation error
template <typename T>
class A
{
template <std::enable_if_t<std::is_signed_v<T>, bool> = true>
constexpr value_type determinant()
{
}
}
我想仅当类型 T
是有符号类型时才实例化行列式函数
所以我尝试了这段代码,但是当类型 T
是无符号编译器时,编译器仍然尝试实例化行列式函数。
我不想针对每个签名类型专门化模板函数 T
。
我想使用 std::is_signed_v
类型特征来简化代码
使用 SFINAE,当测试的条件与方法本身的模板参数相关时,您可以 enable/disable class 的方法。无法测试 class.
的模板参数您可以解决通过默认使用 class/struct 模板参数类型的方法模板参数传递的问题。
例如
#include <iostream>
#include <type_traits>
template <typename T>
struct foo
{
template <typename U = T,
std::enable_if_t<std::is_signed_v<U>, bool> = true>
constexpr std::size_t bar ()
{ return sizeof(T); }
};
int main()
{
foo<signed int> fs;
foo<unsigned int> fu;
fs.bar(); // compile
//fu.bar(); // compilation error
}
这个解决方案的问题是你可以“劫持”它解释一个模板参数
fu.bar(); // compilation error
fu.bar<int>(); // compile
为了避免劫持风险,您可以(其他解决方案也是可能的,但这是我的首选)在 U
// .......VVVVVVVV add this to avoid the hijacking problem
template <int ...,
typename U = T,
std::enable_if_t<std::is_signed_v<U>, bool> = true>
constexpr std::size_t bar ()
{ return sizeof(T); }
// ...
fu.bar(); // compilation error
fu.bar<int>(); // compilation error
fu.bar<1, 2, 3, int>(); // compilation error