gpt4 book ai didi

c++ - 函数模板和 type_traits 的问题

转载 作者:行者123 更新时间:2023-11-30 05:13:54 26 4
gpt4 key购买 nike

我有一个函数“has_holes”,它应该根据掩码计算一些东西。位数由“掩码”的类型决定。因此我想使用模板。此外,我只想允许 has_holes 的实例化,它按值获取参数。所以我添加了一个类型特征“remove_all_t”,它给出了底层类型。但是当我这样做时,我无法再构建它并得到错误:

“错误:没有匹配函数来调用‘has_holes(unsigned int&)”注意:候选模板被忽略:无法推断模板参数“BASE_TYPE”

但是,如果我明确调用 funktion 实例化“has_holes,它就可以工作。我搞砸了模板实例化和类型推导规则吗?或者我的错误在哪里?

代码如下:

#include <iostream>
#include <limits>
#include <type_traits>
#include <experimental/type_traits>


//removes everything except arrays []
template<class T> struct remove_all { typedef T type; };
template<class T> struct remove_all<T*> : remove_all<T> {};
template<class T> struct remove_all<T&> : remove_all<T> {};
template<class T> struct remove_all<T&&> : remove_all<T> {};
template<class T> struct remove_all<T const> : remove_all<T> {};
template<class T> struct remove_all<T volatile> : remove_all<T> {};
template<class T> struct remove_all<T const volatile> : remove_all<T> {};
template<class T>
using remove_all_t = typename remove_all<T>::type;

template<typename BASE_TYPE, class = typename std::enable_if_t<std::experimental::is_unsigned_v<BASE_TYPE>, BASE_TYPE>>
bool has_holes(remove_all_t<BASE_TYPE> mask){ //remove "remove_all_t<>" and it will work

static_assert(std::numeric_limits<unsigned int>::max() > std::numeric_limits<decltype(mask) >::digits, "Base_type has to much digits max_digits=std::numeric_limits<unsigned int>::max()");
for (unsigned int pos{1}; pos<std::numeric_limits<decltype(mask)>::digits; ++pos ){
;//algorithm will be placed here, not implemented yet
}
return true;
}

int main()
{
unsigned int mask = 0b00110011;
auto result = has_holes<unsigned int>(mask); //works
auto result2 = has_holes(mask);//error: no matching function for call to 'has_holes(unsigned int&)'|
std::cout<<result<<" ..."<<result2<<std::endl;
return 0;
}

最好的问候,亨德里克

最佳答案

在 C++ 中,模板推导不是无限的。它将拒绝尝试反转可能的图灵完备过程。

C++ 标准称之为非推导上下文:模板参数不会被推导的上下文。

remove_all_t<BASE_TYPE>引入一个非推导的上下文。因为当您通过 remove_all_t<X> 这样的模板映射类型时理论上映射过程可以是图灵完备的。

一般来说,模板类型映射不会告诉 C++ 如何反转它们。该标准告诉编译器不要尝试。

删除 remove_all_t<BASE_TYPE>并替换为 BASE_TYPE它将始终被推导为一个值。

如果怕有人路过int&显式作为模板类型参数,添加 static_assert( std::is_same<remove_all_t<BASE_TYPE>, BASE_TYPE>::value, "values only");到函数体。

关于c++ - 函数模板和 type_traits 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43679384/

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