(Visual-)用于字符串文字的C ++模板类型推断 - VS 2010 vs VS 2017

时间:2017-10-19 14:55:59

标签: c++ templates visual-c++ type-inference

在尝试为字符串文字添加模板特化时,我注意到VS 2017编译器和VS 2010编译器之间的行为存在差异(两者都来自VS 2017)

这是有问题的代码:

#include <iostream>

template <typename T>
struct foo
{
    static const int a = -1;
};

template <size_t n>
struct foo<char[n]>
{
    static const int a = 0;
};

template <size_t n>
struct foo<const char[n]>
{
    static const int a = 1;
};

template <typename T>
int bar(const T& x)
{
#pragma message (__FUNCSIG__)
    return foo<T>::a;
}

int main()
{
    std::cout << _MSC_VER << '\n';
    std::cout << bar("a") << '\n';
}

使用VS 2017的默认编译器运行:

int __cdecl bar<char[2]>(const char (&)[2])
1911
0

使用VS 2010编译器运行:

int __cdecl bar<const char[2]>(const char (&)[2])
1600
1

如您所见,对于旧编译器,T被推断为const char[2],而对于新编译器,char[2]被推断为<a href="https://go.twitch.tv/ESL_SC2" target="blank"> <h>click me</h> </a>` 。改变了什么?这是Visual Studio中的错误修复/错误,还是在C ++ 11 / C ++ 14中更改了正确的行为?

尝试使用tio.run(gcc和clang),似乎VS 2017是对的,这是正确的吗?

1 个答案:

答案 0 :(得分:1)

这是简单的类型匹配。

您的功能需要const T&。如果我传递一个整数,T将被推断为int,因此签名为const int&。将其推导为const int只会是多余的。

正如您所看到的,您的参数已经作为其中的const,因此它将被匹配。

肯定是一个MSVC 2010漏洞已经修复了,因为旧版本的visual studio的模板实现质量很低。