c++ - 隐式转换行为不一致

标签 c++ type-conversion

我遇到了一个无法理解c++中隐式转换行为的情况。 代码如下:

template <bool b, int i, unsigned... us>
void foo() {}

template <int i, unsigned... us>
void foo() {return foo<false, i, us...>();}

int main()
{
    foo<true, -1, 0ul, 1ul, 2ul>(); // compiles with clang and gcc > 8 (gcc<=8 gives ambiguous function call)
    foo<true, +1, 0ul, 1ul, 2ul>(); // ambiguous function call error
    foo<-1, 0ul, 1ul, 3ul>(); // compiles with clang and gcc > 8 (gcc<=8 gives ambiguous function call)
    foo<+1, 0ul, 1ul, 3ul>(); // ambiguous function call error
}

对于 main() 中的第 1 行和第 2 行,编译器似乎仅针对正整数将 int 隐式转换为 unsigned(这是可以理解,但是这有什么规则吗?)

对于 main() 中的第 3 行和第 4 行,编译器似乎仅针对正整数将 int 隐式转换为 bool。我不明白为什么。

背景:理想情况下,我想要一个类似的构造来工作,这实际上会导致 bool 模板参数的默认值。但由于参数包和 C++ 隐式内置转换,这似乎很困难。

最佳答案

非类型模板参数必须是模板参数类型的转换后的常量表达式

转换后的常量表达式特别不允许缩小转换,在整数类型之间的常量表达式求值的情况下,这意味着如果转换会更改数值,则不允许转换。

这特定于转换的常量表达式要求。如果这些是函数参数和参数,则 -1 的隐式转换至unsigned是被允许的,并且它也有一个明确定义的结果,尽管显然不具有相同的数值 -1 .

因此在 foo<true, -1, 0ul, 1ul, 2ul>();需要 unsigned 的模板处于该位置 -1作为过载候选者确实不可行。

bool 转换,表示从其他标量类型到 bool 的转换根本没有在转换常量表达式允许的转换列表中列出(请参阅 [expr.const]/10 ),据我所知,应该使用 bool 进行重载。在第一个位置对于两者来说都是不可行的 foo<-1, 0ul, 1ul, 3ul>();foo<+1, 0ul, 1ul, 3ul>(); 。我不确定为什么编译器认为后者不明确。根据CWG issue 1407的决议作为非缺陷,从 int 进行转换bool 的模板参数模板参数确实是不允许的,但编译器的行为不符合标准,并且似乎将其视为范围为 0 的整型类型。/1 .

我不知道GCC <8有什么问题。我猜这只是一个错误,它认为过载不明确。

关于c++ - 隐式转换行为不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73129518/

相关文章:

C++11 的采用和兼容性策略?

c++ - 为什么这个涉及重载运算符和隐式转换的 C++ 表达式不明确?

c++ - 创建用于写入 TCP 套接字的消息

c# - 括号和赋值运算符顺序

c++ std 正则表达式为什么不匹配?

sql - 微软 SQL : Should ISDATE() Return "1" when Cannot Cast as Date?

python - '020-06-08 17 :11:02+00:00' I want to extract the date from this time format in Python using datetime

python - Pandas 将字符串列和 NaN( float )转换为整数,并保留 NaN

c - C语言中涉及无符号类型的对象的类型转换

c++ - 枚举运算符不工作