Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 隐式转换应该在模板参数的上下文中工作吗?_C++_Templates_Language Lawyer_Implicit Conversion_Non Type - Fatal编程技术网

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