s4y*_*s4y 7 c++ templates template-argument-deduction
假设我有一个模板函数,assign().它接受一个指针和一个值,并将值赋给指针的目标:
template <typename T> void assign(T *a, T b) { *a = b; }
int main() {
double i;
assign(&i, 2);
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我总是希望T从第一个参数推断出来,但看起来我没有做好表达这一点.2的类型是int,所以:
deduce.cpp:5:5: error: no matching function for call to 'assign'
assign(&i, 2);
^~~~~~
deduce.cpp:1:28: note: candidate template ignored: deduced conflicting types for parameter 'T' ('double' vs. 'int')
template void assign(T *a, T b) { *a = b; }
有没有办法可以声明assign()第二个参数不参与模板参数推导?
Ben*_*igt 13
使用两个类型参数可能是最好的选择,但是如果你真的只想从第一个参数执行演绎,只需使第二个不可推导:
template<typename T>
void assign( T* a, typename std::identity<T>::type b );
Run Code Online (Sandbox Code Playgroud)
该答案的早期版本建议使用C++ 11中引入的模板别名功能.但模板别名仍然是一种可推导的背景.阻止std::identity和减少std::remove_reference推理的主要原因是模板类可以是专用的,因此即使你有一个模板类型参数的typedef,另一个特化也可能有一个相同类型的typedef.由于可能存在歧义,因此不会进行演绎.但模板别名排除了特殊化,因此仍然会发生演绎.
小智 0
C++20std::type_identity可用于建立非推导上下文:
#include <type_traits>
template <typename T>
void assign(T *a, std::type_identity_t<T> b) {
*a = b;
}
int main() {
double i;
assign(&i, 2);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1630 次 |
| 最近记录: |