需要推导参数*之前*用户参数的模板参数
Template parameters that require deduced argument *before* user arguments
我有一个函数,我希望其中的参数被部分推导出来,而其余的(主要是非类型参数)由用户提供(作为强制在编译时提供它们的一种方式)。然而,这个非类型用户来源参数的类型是推导出来的,因此它必须在用户参数之前。这打破了用户推导出第一个参数的能力。我在下面有一个小例子,它没有编译,展示了我在说什么。
template <typename T, T N>
class int_const {};
template <typename T, T M, T N>
auto add(int_const<T, N> a) {
return int_const<T, N + M>();
}
int main(void) {
int_const<int, 1> a;
add<32>(a);
// add<int, 32>(a); does compile, but requires the user to know or extract that first argument
return 0;
}
是否支持模板函数调用,如 main()
所示?
如果能用C++17,就可以用auto
换M
值
template <auto M, typename T, T N>
auto add(int_const<T, N> a) {
return int_const<T, N + M>();
}
所以可以这样调用
add<32>(a);
在 C++17 之前...好吧,我看不到不解释类型的方法。
正如 Jarod42 所指出的,auto M
还拦截了不同类型的值。
如果你想强加 M
的类型正好是 T
,你可以使用 SFINAE;举例如下
template <auto M, typename T, T N,
std::enable_if_t<std::is_same_v<T, decltype(M)>, bool> = true>
auto add(int_const<T, N> a) {
return int_const<T, N + M>();
}
所以你从
得到错误
add<32u>(a);
add<short{32}>(a);
但也许您可以放宽要求并接受 decltype(M)
不完全是 T
,而且只是 M
正在缩小可转换为 T
。
也许
template <auto M, typename T, T N>
auto add(int_const<T, N> a) {
return int_const<T, N + T{M}>();
} // .......................^^^^
所以
add<32u>(a);
add<short{32}>(a);
被编译是因为 32u
和 short{32}
正在缩小可转换为 int
其中
add<(unsigned long)(-1)>(a);
给出编译错误,因为 (unsigned long)(-1)
(通常是 unsigned long
的更大可能值)不能缩小到 int
.
我有一个函数,我希望其中的参数被部分推导出来,而其余的(主要是非类型参数)由用户提供(作为强制在编译时提供它们的一种方式)。然而,这个非类型用户来源参数的类型是推导出来的,因此它必须在用户参数之前。这打破了用户推导出第一个参数的能力。我在下面有一个小例子,它没有编译,展示了我在说什么。
template <typename T, T N>
class int_const {};
template <typename T, T M, T N>
auto add(int_const<T, N> a) {
return int_const<T, N + M>();
}
int main(void) {
int_const<int, 1> a;
add<32>(a);
// add<int, 32>(a); does compile, but requires the user to know or extract that first argument
return 0;
}
是否支持模板函数调用,如 main()
所示?
如果能用C++17,就可以用auto
换M
值
template <auto M, typename T, T N>
auto add(int_const<T, N> a) {
return int_const<T, N + M>();
}
所以可以这样调用
add<32>(a);
在 C++17 之前...好吧,我看不到不解释类型的方法。
正如 Jarod42 所指出的,auto M
还拦截了不同类型的值。
如果你想强加 M
的类型正好是 T
,你可以使用 SFINAE;举例如下
template <auto M, typename T, T N,
std::enable_if_t<std::is_same_v<T, decltype(M)>, bool> = true>
auto add(int_const<T, N> a) {
return int_const<T, N + M>();
}
所以你从
得到错误add<32u>(a);
add<short{32}>(a);
但也许您可以放宽要求并接受 decltype(M)
不完全是 T
,而且只是 M
正在缩小可转换为 T
。
也许
template <auto M, typename T, T N>
auto add(int_const<T, N> a) {
return int_const<T, N + T{M}>();
} // .......................^^^^
所以
add<32u>(a);
add<short{32}>(a);
被编译是因为 32u
和 short{32}
正在缩小可转换为 int
其中
add<(unsigned long)(-1)>(a);
给出编译错误,因为 (unsigned long)(-1)
(通常是 unsigned long
的更大可能值)不能缩小到 int
.