【发布时间】:2016-01-16 08:52:21
【问题描述】:
以下代码使用 VS15 Community 编译并打印出“Hello”。
#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();
}
我认为这是不允许编译的。
我在玩,代码有点复杂。我天真地以为这会起作用,但突然意识到这段代码不应该编译,因为你不能创建Func<void>(或者我错了吗?)。
- 我找到神奇的解决方法了吗?
- 这是 C++14 标准的新行为吗?
- 或者它只是一个编译器错误?
编辑:以下更简化的版本无法编译。
#include <functional>
#include <iostream>
template<typename T>
using Func = std::function<void( T )>;
int main()
{
Func<void> hello = [] { std::cout << "Hello\n"; };
hello();
}
- 那么为什么上面的代码可以按我最初的预期编译和工作?
- 这是一个正确的实现,如果不是,它会是什么样子?
【问题讨论】:
-
foo(void)和using X = void; foo(X);之间存在天壤之别。如果其他编译器接受这一点,我会感到惊讶。 -
哦,我太确定了。标准规定“参数列表
(void)等效于空参数列表。”,但没有指定(void)是文字文本。并且没有专门的语法产生,g++和Visual C++都编译void foo(X),其中X是void的名字,它们编译调用foo()。 -
也许我最好明确指出,
(void)的解释是指一个函数,其中单个参数的 type 实际上是void,然后表示一个没有参数的函数,不能很好地与使用参数调用函数的模板代码一起工作,即它是不切实际的。然而,MSVC 和 MinGW g++ 都接受非模板foo(My_void)并调用foo()。 :( -
@Cheersandhth.-Alf 在DR 577 之后,规则是“由一个非依赖类型
void的单个未命名参数组成的参数列表相当于一个空参数列表”。跨度> -
@T.C.:所以,这在 C++14 中发生了变化。 DR 表明 C++11 和更早版本的自然阅读,因为
(void)是文字文本(不允许typedef),是那些版本的正确阅读。谢谢!
标签: c++ c++11 visual-studio-2015 language-lawyer type-alias