Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.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++ VS2015中模板类型别名出现意外行为_C++_C++11_Visual Studio 2015_Language Lawyer_Type Alias - Fatal编程技术网

C++ VS2015中模板类型别名出现意外行为

C++ VS2015中模板类型别名出现意外行为,c++,c++11,visual-studio-2015,language-lawyer,type-alias,C++,C++11,Visual Studio 2015,Language Lawyer,Type Alias,下面的代码使用VS15社区编译并打印出“Hello” #包括 #包括 模板 使用void\u模板\u别名\u t=void; 模板 使用Func=std::function; 模板 使用FuncVoid=Func; int main() { FuncVoid hello=[]{std::cout 或者它只是一个编译器错误 如@T.C.所述,与以下内容相关: […]在那里 是否有人对函数模板的处理表示担忧 如果C++规则发生改变,类模板的成员函数: 对于模板参数T,将使用一个单一参数的函数 类型为

下面的代码使用VS15社区编译并打印出“Hello”

#包括
#包括
模板
使用void\u模板\u别名\u t=void;
模板
使用Func=std::function;
模板
使用FuncVoid=Func;
int main()
{
FuncVoid hello=[]{std::cout
或者它只是一个编译器错误

如@T.C.所述,与以下内容相关:

[…]在那里 是否有人对函数模板的处理表示担忧 如果C++规则发生改变,类模板的成员函数: 对于模板参数
T
将使用一个单一参数的函数 类型为
T
的函数,如果用
T=void

这是一个合理的投诉,但不幸的是,成员函数/成员函数模板和类型ID同样受到解决方案的影响:

由单个非依赖类型的未命名参数组成的参数列表相当于空参数列表

因此,这两个代码段的格式都不正确,因为参数的类型确实是依赖的


它是一个正确的实现吗?如果不是,它会是什么样子

没有正确的实现。如果需要具有空参数列表的函数类型,则必须独立于模板参数指定该类型

那么,为什么上面的代码按照我最初的预期进行编译和工作呢


我的最佳猜测是:VC++在确保参数类型不是依赖类型“cv
void
”之后,但在进行“
void
->空列表转换”之前,替换了
void\u template\u alias\u t
”。然而,通常很难理解VC++(或任何编译器)是如何进行空列表转换的内部思考。

使用X=void;foo(X);
之间有着天壤之别。

如果其他编译器接受这一点,我会感到惊讶。哦,我太确定了。标准规定“参数列表
(void)
等同于空参数列表。”,但没有指定
(void)是文字文本,并且没有特殊的语法生成,G++和VisualC++都编译<代码>无效FO(x)< /> >其中代码< >代码> >代码>空> <代码>,他们编译了调用<代码>()/代码>。也许我最好明确地指出,解释在哪里<代码>(空格)
指的是一个函数,其中单个参数的类型实际上是
void
,然后表示一个没有参数的函数,不适用于使用参数调用函数的模板代码,也就是说,这是不切实际的。然而MSVC和MinGW g++都接受非模板
foo(My_void)
并调用
foo()
:(@cheerrandhth.-Alf之后,规则是“由一个非依赖类型的未命名参数组成的参数列表
void
相当于一个空参数列表”。@T.C.:因此,这在C++14中发生了变化。DR表明C++11和更早版本的自然读取,如
(void)
是文本(不允许使用
typedef
),是这些版本的正确选项。谢谢!
#include <functional>
#include <iostream>

template<typename T>
using void_template_alias_t = void;

template<typename T>
using Func = std::function<void( T )>;

template<typename T>
using FuncVoid = Func<void_template_alias_t<T>>;

int main()
{
    FuncVoid<void> hello = [] { std::cout << "Hello\n"; };
    hello();
}
#include <functional>
#include <iostream>

template<typename T>
using Func = std::function<void( T )>;

int main()
{
    Func<void> hello = [] { std::cout << "Hello\n"; };
    hello();
}