非类型参数包奇怪地扩展

时间:2018-04-03 17:37:59

标签: c++ visual-c++

请考虑以下代码:

#include <iostream>
#include <typeinfo>

template <size_t... s>
struct str
{
    typedef void(&ftype)(decltype(s)...);
};

int main()
{
    std::cout << typeid(str<3, 4, 5>::ftype).name() << std::endl;
}

在VS2017中编译时,此程序的输出为int __cdecl(unsigned int),即使根据我对...运算符的理解,它也应扩展所有参数。奇怪的是,如果我将代码修改为:

#include <iostream>
#include <typeinfo>

template <size_t... s>
struct str
{
    template <class Func=void(&)(decltype(s)...)>
    using ftype = Func;
};

int main()
{
    std::cout << typeid(str<3, 4, 5>::ftype<>).name() << std::endl;
}

结果是void (__cdecl*)(unsigned int,unsigned int,unsigned int),正如所料。

这是VC ++中的错误吗?

1 个答案:

答案 0 :(得分:2)

有两种方法可以查看您的问题。 C ++语言级别和QoI级别。

在语言层面,没有错误。 typeid(...).name()返回一些实现定义的字符串。对它没有任何限制。它甚至可以为所有类型返回相同的字符串。

就MSVC本身而言,因为它可以通过您的解决方法确认参数的实际数量,这显然是一个问题。所以是的,人们可以在这里看到改进的机会,这可能需要一份报告。