我在使用可变参数模板时遇到了问题,但问题与可变参数模板无关,可以在没有它们的情况下重现。 该问题与继承类和基类中相同类型的名称有关。
我已将代码简化为以下代码段:
#include <typeinfo>
#include <iostream>
struct A
{
int member;
};
struct B: public A
{
typedef A NEXT;
short member;
};
struct Foo: public B
{
typedef B NEXT;
void Check()
{
std::cout << typeid(NEXT::member).name() << '\n';
std::cout << typeid(NEXT::NEXT::member).name() << '\n';
NEXT::NEXT::member = 1;
NEXT::member = 2;
std::cout << NEXT::NEXT::member << '\n';
std::cout << NEXT::member << '\n';
};
};
int main()
{
Foo foo;
foo.Check();
}
它在没有警告的情况下编译并与GCC和clang一起工作,但它会在MSVC中产生错误的输出(至少在Visual Studio 2015 Update 1中)。
似乎名称中发生了一些冲突,它将NEXT::NEXT::member
视为NEXT::member
,但在同一个地方,它位于typeid
(以及std::is_same
})。
使用GCC或clang编译时,输出为:
s
i
1
2
但是在MSVC的情况下,输出是:
short
int
2
2
以下代码在没有GCC或clang警告的情况下进行编译,但正如预期的那样会在MSVC中产生错误:
struct A
{
int member;
};
struct B: public A
{
typedef A NEXT;
short member;
};
struct Foo: public B
{
typedef B NEXT;
short& GetB() { return NEXT::member; };
int& GetA() { return NEXT::NEXT::member; };
};
MSVC错误:
source_file.cpp(18): error C2440: 'return': cannot convert from 'short' to 'int &'
以上代码有效吗?这是MSVC的问题还是我以某种方式利用UB?
在MSVC 2015更新3中无法重现该问题。