gpt4 book ai didi

c++ - 如何使用元编程过滤 const 类型和非 const 类型?

转载 作者:行者123 更新时间:2023-11-30 00:50:16 25 4
gpt4 key购买 nike

我有这个代码

#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不是常数,我用了typeiddecltype打印 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 参数类型生成两个不同的函数;函数模板实例化的参数类型在任何情况下都将是 const 限定的:您通过说 const T& 来请求它而不是,比如说,T& .


您可以通过 cv 限定函数参数来推断参数的常量性:

template<typename T>
void deduce(T&);

但是,这将无法绑定(bind)到非常量临时值(右值)。为了也支持它们,您可以使用通用引用:

template<typename T>
void deduce(T&&);

这将为 T 推导出左值引用类型如果参数是左值,如果参数是右值则没有引用。 const-ness 将被正确推导。

例如,如果参数的类型为 const A并且是一个左值,T将被推断为 const A& .那么函数参数是const A& && , 折叠为 const A& (左值引用)。如果参数是右值,T将被推断为 const A ,函数参数变为const A&& (右值引用)。

注意自 T在这种情况下可以作为引用,您需要在检查 const-ness 之前将其删除:std::is_const< typename std::remove_reference<T>::type >::value .

关于c++ - 如何使用元编程过滤 const 类型和非 const 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25554918/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com