c++ - VS2015 中模板类型别名的意外行为

标签 c++ c++11 visual-studio-2015 language-lawyer type-alias

以下代码使用 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();
}
  • 那么,为什么上面的代码可以按照我最初的预期编译和工作?
  • 这是一个正确的实现吗,如果不是,它会是什么样子?

最佳答案

Or is it simply a compiler bug?

那个。正如@T.C.所提到的,CWG #577是相关的:

[…] there was some concern expressed over the treatment of function templates and member functions of class templates if the C++ rule were changed: for a template parameter T, would a function taking a single parameter of type T become a no-parameter function if it were instantiated with T = void?

这是一个合理的投诉,但对您来说很不幸,成员函数/成员函数模板和 type-id 受到该决议的同等影响:

A parameter list consisting of a single unnamed parameter of non-dependent type void is equivalent to the an empty parameter list.

因此,您的两个片段都是格式错误的,因为参数的类型确实是依赖的。


Is it a correct implementation, if not, how would it look like?

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

So why is the code above compiling and working as I first expected?

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

关于c++ - VS2015 中模板类型别名的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33190183/

相关文章:

C++ ASCII游戏图

c++ - 如何从 boost::ptr_vector 中删除 "this"

c++ - 任何碱基到任何碱基 (2-16) 的转换都会出错

c++ - 对c++ vector 的交集

c# - 在 Visual Studio C# 中更改资源文件的代码生成器

c++ - C++ 中的 BitTorrent Peer Wire 消息

c++11 - 返回 lambda 捕获函数参数引用

visual-c++ - 从 Visual Studio 2015 企业更新 1 面向 Windows XP

c++ - 如何在 Windows 7 上使用 DirectX 11 和 Visual Studio 2015 工具集 v140

c++ - 如何为 C++0x/11 和非 C++0x/11 制作 header ?