C++ 隐式转换应该在模板参数的上下文中工作吗?
更明确地说,编译器是否应该在C++ 隐式转换应该在模板参数的上下文中工作吗?,c++,templates,language-lawyer,implicit-conversion,non-type,C++,Templates,Language Lawyer,Implicit Conversion,Non Type,更明确地说,编译器是否应该在enable\u if的第一个参数中将true\u类型值视为true,因为true\u类型实际上是std::integral\u常量,并且integral\u常量定义了类型转换函数运算符值\u类型 以下是最简单的测试代码: #包括 模板 std::如果启用,则启用 测试(T) { } int main() { 测试(正确); } 它被GCC和Clang接受,但被MSVC拒绝(直到Visual Studio 2019 v16.3.1)。您的代码格式良好,应该考虑重新编
enable\u if
的第一个参数中将true\u类型
值视为true
,因为true\u类型
实际上是std::integral\u常量
,并且integral\u常量
定义了类型转换函数运算符值\u类型
以下是最简单的测试代码:
#包括
模板
std::如果启用,则启用
测试(T)
{
}
int main()
{
测试(正确);
}
它被GCC和Clang接受,但被MSVC拒绝(直到Visual Studio 2019 v16.3.1)。您的代码格式良好,应该考虑重新编写
可与非类型模板参数一起使用的模板参数可以是模板参数的任何类型
类型为T
的转换常量表达式是一个表达式
键入T
,其中转换后的表达式为
常量表达式,并且隐式转换序列包含
仅:
用户定义的转换(因此可以在需要整数类型的地方使用类)constexpr
std::is_pod
转换的bool
是转换的常量表达式,可以应用
作为解决方法(我想您已经意识到),您可以使用
std::is_pod_v
(从C++17开始)或std::is_pod_v::value
。回答更一般的问题,是的,应该接受它。MSVC默认为C++14,因此我将根据该标准给出答案
[temp.arg.nontype]
1非类型、非模板参数的模板参数
应为以下各项之一:
-对于整型或枚举型非类型模板参数
类型,类型的转换常量表达式([expr.const])
模板参数;或
[expr.const]
整型常数表达式是整型或非整型常数的表达式
非范围枚举类型,隐式转换为prvalue,其中
转换后的表达式是核心常量表达式。皈依
T类型的常量表达式是一个隐式转换的表达式
转换为类型为T的prvalue,其中转换后的表达式为核心
常量表达式和隐式转换序列仅包含
用户定义的转换,从左值到右值的转换([conv.lval]),
积分促销([conv.prom])和积分转换
([conv.integral]),而不是缩小转换([dcl.init.list])
由于integral\u constant
支持constepr操作符T()
,并且此用户定义的转换可能出现在转换后的常量表达式中,因此您的代码完全有效。MSVC似乎被它的解析所困扰。因为当我尝试你的例子时,它吐了出来
(4):错误C2059:语法错误:“”
(4) :错误C2143:语法错误:缺少“;”在“{”之前
(4) :错误C2143:语法错误:在“;”之前缺少“>”
(4) :错误C2988:无法识别的模板声明/定义
(4) :错误C2059:语法错误:';'
(4) :错误C2447:“{”:缺少函数头(旧式正式列表?)
(4) :错误C2988:无法识别的模板声明/定义
(4) :错误C2059:语法错误:'>'
(6) :错误C2143:语法错误:在“{”之前缺少“;”
(6) :错误C2447:“{”:缺少函数头(旧式正式列表?)
(11) :错误C3861:“测试”:找不到标识符
微软对模板的处理在历史上与GCC或Clang不同,这可能是解析中出现这个问题的原因。
std::enable_如果
起作用的话。谢谢,我知道解决方法。我只是想知道这是否是MSVC的错误。@YongweiWu我想是的,特别是当GCC和Clang都说是的时候。我想我忘记了在它上面,但我确实在命令行上指定了cl/EHsc/std:c++17 test.cpp
。@YongweiWu-没有什么区别。c++17添加了更多可能的常量表达式。因此,在c++14中有效的仍然是在c++17中有效的常量表达式。
<source>(4): error C2059: syntax error: '<end Parse>'
<source>(4): error C2143: syntax error: missing ';' before '{'
<source>(4): error C2143: syntax error: missing '>' before ';'
<source>(4): error C2988: unrecognizable template declaration/definition
<source>(4): error C2059: syntax error: ';'
<source>(4): error C2447: '{': missing function header (old-style formal list?)
<source>(4): error C2988: unrecognizable template declaration/definition
<source>(4): error C2059: syntax error: '>'
<source>(6): error C2143: syntax error: missing ';' before '{'
<source>(6): error C2447: '{': missing function header (old-style formal list?)
<source>(11): error C3861: 'test': identifier not found