如何使用元编程过滤常量类型和非常量类型
How to filter const types and non const types using meta programing?
我有这个代码
#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;
}
我试图在编译时知道常量参数和非常量参数的总大小。当前输出为8,由于某种原因,编译器认为b
不是常数,我使用typeid
和decltype
打印a
和b
的类型,实际上输出显示b
是int
,而不是我预期的const int
。我错过了什么?有可能将一组可变参数分为常量参数和非常量参数吗?
考虑这个函数模板:
template<typename T>
void deduce(const T&);
如果让编译器从参数表达式推导出T
的类型,则推导出的类型永远不会是const
:它将尝试使函数参数的const T
与用于调用函数的参数表达式的类型相同。例如:
struct cls {};
const cls c;
deduce(c) // deduces T == cls
通过推导T == cls
,编译器成功地使const T
与参数类型const cls
相同。编译器没有理由为常量和非常量参数类型生成两个不同的函数;函数模板实例化的参数类型在任何情况下都是const限定的:您通过说const T&
而不是说T&
来请求它。
您可以通过而不是cv限定函数参数来推断参数的常量:
template<typename T>
void deduce(T&);
但是,这将无法绑定到非常量临时值(rvalues)。为了支持它们,您可以使用通用参考:
template<typename T>
void deduce(T&&);
如果参数是左值,这将推导出T
的左值引用类型,如果参数是右值,则不推导出引用类型。常数将被正确地推导出来。
例如,如果参数的类型为const A
并且是左值,则T
将被推导为const A&
。函数参数是const A& &&
,它被折叠为const A&
(左值引用)。如果自变量是右值,则T
将被推导为const A
,并且函数参数变为const A&&
(右值引用)。
注意,由于T
在这种情况下可以是一个引用,因此在检查常量之前需要删除它:std::is_const< typename std::remove_reference<T>::type >::value
。
- 如何为具有常量类型的函数正确转换来自 DLsym 的返回值?
- 常量和非常量类型的相同模板专用化
- 另一个:从"常量类型*"到"类型*"的转换无效
- 派生类中函数参数变化的虚函数按常量类型在"function parameter"会破坏虚拟机制吗?
- 模板和常量类型
- 返回对常量指针的引用,指向常量类型
- 错误:常量类型为c++的单元化成员
- 如何在不重复函数的情况下推导出常量和非常量类型
- JUCE - 成员函数不可行:'this'参数具有常量类型
- 未找到采用常量类型的左操作数的'=='运算符
- 重载全常量类型的复制赋值运算符的正确方法是什么?
- 忽略候选模板:无法将"常量类型参数-0-0 *"与"字符"匹配
- C++中的部分常量类型转换
- 常量类型之间的区别
- 提升::任何构造函数 - 常量类型重载分辨率
- 如何声明模板常量类型
- 编译时生成的常量类型 ID
- 转换为常量类型,初始化数组
- 正在获取模板中的非常量类型
- 如何使用元编程过滤常量类型和非常量类型