歧义情况下的类型名解析
typename resolution in cases of ambiguity
我在玩Visual Studio和模板。
考虑以下代码
struct Foo
{
struct Bar
{
};
static const int Bar=42;
};
template<typename T>
void MyFunction()
{
typename T::Bar f;
}
int main()
{
MyFunction<Foo>();
return 0;
}
当我在Visual Studio 2008和11中编译时,我得到以下错误
error C2146: syntax error : missing ';' before identifier 'f'
Visual Studio在这方面是否正确?代码是否违反了任何标准?
如果我把代码改成struct Foo
{
struct Bar
{
};
static const int Bar=42;
};
void SecondFunction( const int& )
{
}
template<typename T>
void MyFunction()
{
SecondFunction( T::Bar );
}
int main()
{
MyFunction<Foo>();
return 0;
}
编译时没有任何警告。在Foo::BLAH中,成员优于类型,以避免冲突?
编辑g++ 4.2.1的测试
struct Foo
{
static const int Bar=42;
};
void SecondFunction(const int& x)
{
}
template<typename T>
void MyFunction()
{
int x = Foo::Bar;
}
int main()
{
MyFunction<Foo>();
return 0;
}
编译好了。
struct Foo
{
static const int Bar=42;
};
void SecondFunction(const int& x)
{
}
template<typename T>
void MyFunction()
{
SecondFunction(T::Bar);
}
int main()
{
MyFunction<Foo>();
return 0;
}
给了我这些错误
未定义的符号:"Foo::Bar",引用自:在cck498aS.o中无效MyFunction()没有找到Ld:符号
在c++中,命名实体分为三个不同的本体层:值、类型和模板。
如果依赖名称是未知层,那么你必须告诉编译器它是什么:
-
如果你说
typename
,它是一个类型 -
如果输入
template
,则为模板
因此,T::Bar
作为MyFunction
模板中的一个依赖名称,被自动假定为引用一个值,因此int
成员Foo::Bar
。另一方面,在第一个例子中,typename T::Bar
确实指的是成员类型 Foo::Bar
。
您可以看到一个不为人所知的C兼容性规则的效果。在C中,与c++不同的是,如果将类型定义为struct X
或enum X
,则不需要将名称X
引入相应的名称空间,而必须将类型引用为struct X
。因此,在C中,您可以将'X'额外定义为不同的东西,而不会触发冲突的定义。现在在c++中,struct X
确实将名称X
引入了相应的作用域。因此,X
的任何其他定义将被标记为双重定义。然而,能够在经常发生此问题的地方包含C头文件被认为是重要的。因此,引入了一个特殊的规则,无论何时您同时拥有X
的(非typedef)类型定义和X
的另一个定义,这都不会导致错误,但是X
引用了非类型定义,并且为了获得类型定义,您必须在其前面加上相应的类型关键字(即struct X
, emum X
或class X
)。
在你的例子中,这意味着Foo
包含一个名为class Bar
的类型和一个名为Bar
的静态const int,但没有名为Bar
的类型。注意,这里不需要模板;一个简单的全局声明Bar::Foo foo;
也应该失败。
- 为什么在这种情况下,bool 类型的输出等于 0?
- C++默认情况下,指针类型数组的元素是否保证初始化为 nullptr?
- 如何在没有实例的情况下获取非静态方法的类型?
- 如何在不破坏现有应用程序的情况下更改 API 中 stl 容器的数据类型?
- 是否可以在不使用 decltype 的情况下推断先前定义的 extern 变量的类型
- 在没有标识符的情况下如何读取复杂的C++类型声明?
- MSVC 在不知道类型的情况下评估上下文(和错误)
- 我们可以在不知道其真实类型的情况下将基类指针转换为派生类指针吗?
- 如何在不给它任何类型(如整数)的情况下定义某物?
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 将类型映射到整数值后,如何在给定整数值的情况下恢复类型?
- 如何在不违反类型别名规则的情况下解释消息负载?
- msgpack:在不知道类型的情况下解包自定义类
- 对于多态类型T,如何在没有类型T实例的情况下获得指向T的虚拟表的指针
- 在这种特殊情况下,我是否需要在共享内存中使用原子类型
- 为什么在以下情况下不需要为依赖类型使用typename
- 有没有办法在没有reinterpret_cast的情况下保存多种类型的指针?
- 如何定义可以在没有联合的情况下容纳uintptr_t或uint32_t的类型?
- 推荐的方法在不初始化值的情况下使数组类型为 std::unique_ptr?
- 为什么在某些情况下从函数返回类型中删除 cv 限定符?