e27*_*314 1 c++ template-meta-programming c++11 type-deduction
我有这个代码
#include <iostream>
size_t F()
{
return 0;
}
template <class Type, class... NextTypes>
size_t F(const Type& type, const NextTypes&... nextTypes)
{
if (!std::is_const<Type>::value)
return sizeof(type) + F(nextTypes...);
else
return F(nextTypes...);
}
int main()
{
int a = 0;
const int b = 0;
const size_t size = F(a,b);
std::cout << "size = " << size << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我试图在编译时知道常量参数和非常量参数的总大小.当前输出为8,由于某种原因,编译器认为b不是常量,我使用typeid并decltype打印类型a和b输出显示确实b是一个int而不是const int我预期的.我错过了什么?是否有可能将一组可变参数分别为const参数和非const?
考虑这个功能模板:
template<typename T>
void deduce(const T&);
Run Code Online (Sandbox Code Playgroud)
如果让编译器T从参数表达式中推导出类型,则推导的类型将永远不会const:它将尝试使const T函数参数与用于调用函数的参数表达式的类型相同.例如:
struct cls {};
const cls c;
deduce(c) // deduces T == cls
Run Code Online (Sandbox Code Playgroud)
通过推导T == cls,编译器成功地使const T参数类型相同const cls.编译器没有理由为const和非const参数类型生成两个不同的函数; 在任何情况下,函数模板实例化的参数类型都将是const限定的:你通过说const T&而不是说来请求它T&.
您可以通过不对 cv限定函数参数来推断参数的常量:
template<typename T>
void deduce(T&);
Run Code Online (Sandbox Code Playgroud)
但是,这将无法绑定到非const临时值(rvalues).为了支持它们,您可以使用通用引用:
template<typename T>
void deduce(T&&);
Run Code Online (Sandbox Code Playgroud)
T如果参数是左值,这将推导出左值引用类型,如果参数是右值,则不会引用参考值.常量将被正确推导出来.
例如,如果参数具有类型const A且是左值,T则将推导出const A&.然后是函数参数const A& &&,它被折叠为const A&(左值引用).如果参数是rvalue,将推T导出const A,并且函数参数变为const A&&(rvalue-reference).
请注意,因为T在这种情况下可以作为引用,所以在检查const-ness之前需要删除它:std::is_const< typename std::remove_reference<T>::type >::value.
| 归档时间: |
|
| 查看次数: |
132 次 |
| 最近记录: |