C++ 中的从属名称是什么?
What are dependent names in C++?
C++ 名称何时“依赖”?显然,当它在同一范围内使用类型定义时,它并不依赖。但是,当它在 this 范围的嵌套范围内使用类型定义时,它是依赖的。考虑以下示例:
示例 A:
template <typename T>
struct some_struct
{
struct B
{
int b_;
};
T some_member_func();
T a_;
};
template <typename T>
T some_struct<T>::some_member_func()
{
using hello = B;
return a_;
}
..编译正常。
示例 B(嵌套):
template <typename T>
struct some_struct
{
struct B
{
struct C {
int c_;
};
};
T some_member_func();
T a_;
};
template <typename T>
T some_struct<T>::some_member_func()
{
using hello = B::C;
return a_;
}
..发出以下错误:
<source>: In member function 'T some_struct<T>::some_member_func()':
<source>:365:19: error: need 'typename' before 'some_struct<T>::B::C' because 'some_struct<T>::B' is a dependent scope
365 | using hello = B::C;
| ^
| typename
为什么 some_struct::B 是依赖范围而不是 some_struct(示例 A)?
如果我读 https://en.cppreference.com/w/cpp/language/dependent_name 正确,那么 B
和 B::C
都是相关的。
但是B
也“引用了当前的实例化”,这使得它可以在没有typename
的情况下使用。这似乎是一种奇特的说法,“它是否是一个类型不受专业化的影响”。
您可以特化 B
以使 B::C
不是类型:
template <>
struct some_struct<int>::B
{
static void C() {}
};
(有趣的是,部分特化没有编译)
但是您无法通过特化阻止 B
成为类型。
C++ 名称何时“依赖”?显然,当它在同一范围内使用类型定义时,它并不依赖。但是,当它在 this 范围的嵌套范围内使用类型定义时,它是依赖的。考虑以下示例:
示例 A:
template <typename T>
struct some_struct
{
struct B
{
int b_;
};
T some_member_func();
T a_;
};
template <typename T>
T some_struct<T>::some_member_func()
{
using hello = B;
return a_;
}
..编译正常。
示例 B(嵌套):
template <typename T>
struct some_struct
{
struct B
{
struct C {
int c_;
};
};
T some_member_func();
T a_;
};
template <typename T>
T some_struct<T>::some_member_func()
{
using hello = B::C;
return a_;
}
..发出以下错误:
<source>: In member function 'T some_struct<T>::some_member_func()':
<source>:365:19: error: need 'typename' before 'some_struct<T>::B::C' because 'some_struct<T>::B' is a dependent scope
365 | using hello = B::C;
| ^
| typename
为什么 some_struct::B 是依赖范围而不是 some_struct(示例 A)?
如果我读 https://en.cppreference.com/w/cpp/language/dependent_name 正确,那么 B
和 B::C
都是相关的。
但是B
也“引用了当前的实例化”,这使得它可以在没有typename
的情况下使用。这似乎是一种奇特的说法,“它是否是一个类型不受专业化的影响”。
您可以特化 B
以使 B::C
不是类型:
template <>
struct some_struct<int>::B
{
static void C() {}
};
(有趣的是,部分特化没有编译)
但是您无法通过特化阻止 B
成为类型。