为嵌套模板编写 C++17 样式“_v”辅助模板的正确方法
Proper way to write a C++17 style "_v" helper template for a nested template
标准库提供了在编译时确定不同类型特征的模板。例如:
std::is_integral<T>::value
会告诉你某个东西是否是整数类型。
自 C++17 起,为这些类型特征模板添加了快捷方式 "helper templates"。
std::is_integral_v<T>
提供相同的结果而不需要 ::value
类似于std::is_integral
,我有一个相对复杂的模板来判断一种类型是否是另一种类型的特化:
template <typename T, template <typename...> typename Template>
struct is_specialization : std::false_type {};
template <template <typename...> typename Template, typename... Args>
struct is_specialization<Template<Args...>, Template> : std::true_type {};
用法示例如下所示(如果传入的类型是std::complex
的特化,这将启用此模板函数):
#include <complex>
#include <iostream>
#include <type_traits>
template <typename T>
struct MyComplex
{
MyComplex(const T& real, const T& imag)
: real(real)
, imag(imag)
{}
T real() { return this->real; }
T imag() { return this->imag; }
private:
T real;
T imag;
};
// Only enable this template if "T" is a specialization of "std::complex"
template <typename T,
typename = std::enable_if_t<is_specialization<T, std::complex>::value>
>
void foo(T value)
{
std::cout << value.real() << std::endl;
}
int main()
{
std::complex<double> value1{ 1.0, 2.0 };
foo(value1);
std::complex<int> value2{ 1, 2 };
foo(value2);
MyComplex<double> value3{ 1.0, 2.0 };
// Fails to compile because "MyComplex<double>" is not a specialization of "std::complex"
//foo(value3);
}
我想为此编写一个“_v”辅助模板,但我不确定如何编写,因为它涉及嵌套模板。
因为 is_specialization
有两个模板参数,我的第一个想法就是做这样的事情,也许编译器会发现 "T" 和 "U" 可以嵌套类型它自己的,但它似乎不起作用:
template <typename T, typename U>
inline constexpr bool is_specialization_v = is_specialization<T, U>::value;
为这样的东西编写“_v”助手模板的正确方法是什么?还请尝试在答案中解释它是如何工作的,因为我对模板元编程还很陌生,而且我仍在为一些概念而苦苦挣扎。
你的别名参数有误,应该与主模板相同:
template <typename T, template <typename...> typename Template>
inline constexpr bool is_specialization_v = is_specialization<T, Template>::value;
标准库提供了在编译时确定不同类型特征的模板。例如:
std::is_integral<T>::value
会告诉你某个东西是否是整数类型。
自 C++17 起,为这些类型特征模板添加了快捷方式 "helper templates"。
std::is_integral_v<T>
提供相同的结果而不需要 ::value
类似于std::is_integral
,我有一个相对复杂的模板来判断一种类型是否是另一种类型的特化:
template <typename T, template <typename...> typename Template>
struct is_specialization : std::false_type {};
template <template <typename...> typename Template, typename... Args>
struct is_specialization<Template<Args...>, Template> : std::true_type {};
用法示例如下所示(如果传入的类型是std::complex
的特化,这将启用此模板函数):
#include <complex>
#include <iostream>
#include <type_traits>
template <typename T>
struct MyComplex
{
MyComplex(const T& real, const T& imag)
: real(real)
, imag(imag)
{}
T real() { return this->real; }
T imag() { return this->imag; }
private:
T real;
T imag;
};
// Only enable this template if "T" is a specialization of "std::complex"
template <typename T,
typename = std::enable_if_t<is_specialization<T, std::complex>::value>
>
void foo(T value)
{
std::cout << value.real() << std::endl;
}
int main()
{
std::complex<double> value1{ 1.0, 2.0 };
foo(value1);
std::complex<int> value2{ 1, 2 };
foo(value2);
MyComplex<double> value3{ 1.0, 2.0 };
// Fails to compile because "MyComplex<double>" is not a specialization of "std::complex"
//foo(value3);
}
我想为此编写一个“_v”辅助模板,但我不确定如何编写,因为它涉及嵌套模板。
因为 is_specialization
有两个模板参数,我的第一个想法就是做这样的事情,也许编译器会发现 "T" 和 "U" 可以嵌套类型它自己的,但它似乎不起作用:
template <typename T, typename U>
inline constexpr bool is_specialization_v = is_specialization<T, U>::value;
为这样的东西编写“_v”助手模板的正确方法是什么?还请尝试在答案中解释它是如何工作的,因为我对模板元编程还很陌生,而且我仍在为一些概念而苦苦挣扎。
你的别名参数有误,应该与主模板相同:
template <typename T, template <typename...> typename Template>
inline constexpr bool is_specialization_v = is_specialization<T, Template>::value;