需要*在*用户参数之前推导参数的模板参数
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
。
相关文章:
- 使用用户定义的参数调用future/async并调用类方法
- 参数包构造函数在类模板中隐藏用户定义的转换
- 用户输入作为参数C++
- 如何设置默认参数以防用户不输入另一个参数
- 在未显式传递参数时默认使用 lambda 的用户输入
- 如何防止用户指定函数模板参数,迫使其进行推导
- 如何对多个模板参数使用用户定义的推导指南
- 读取用户必须提供一些参数的文件
- 使用用户定义的转换运算符推导函数模板参数
- 用户定义的转换不适用于可变参数函数参数?为什么不呢?
- 用户指定的参数,用于确定在大循环中调用哪个函数
- 有没有办法根据用户参数设置函数指针?
- 指定在用户固定我的应用程序时用于运行应用程序的命令参数
- 用户定义的构造函数重载与参数超类的重载不匹配
- 作为传递给 CPP 类构造函数的参数的用户定义函数
- 如何在 C/C++ 中使用用户定义的参数对库进行编码
- 我如何与C 中的用户输入正确使用参数
- 迫使用户传递已知类型的模板参数,该参数本身是模板
- 推导用户定义的值模板参数(C++2a、P0732R2)
- 基于用户表达式在编译时参数化函数