C++ 你如何理解C++;

C++ 你如何理解C++;,c++,C++,我通常在模板的上下文中遇到这个术语“依赖名称”。然而,我很少接触后者。因此,我自然想了解更多有关从属名称的概念 您如何在模板的上下文和外部理解它?我们鼓励大家以身作则 依赖名称本质上是依赖于模板参数的名称 使用模板时,模板的定义点和实例化点(即实际使用模板的位置)之间存在区别。依赖于模板的名称在实例化时才被绑定,而依赖于模板的名称在定义时才被绑定 一个简单的例子是: template< class T > int addInt( T x ) { return i + x.to

我通常在模板的上下文中遇到这个术语“依赖名称”。然而,我很少接触后者。因此,我自然想了解更多有关从属名称的概念


您如何在模板的上下文和外部理解它?我们鼓励大家以身作则

依赖名称本质上是依赖于模板参数的名称

使用模板时,模板的定义点和实例化点(即实际使用模板的位置)之间存在区别。依赖于模板的名称在实例化时才被绑定,而依赖于模板的名称在定义时才被绑定

一个简单的例子是:

template< class T > int addInt( T x )
{
    return i + x.toInt();
}
templateint addInt(tx)
{
返回i+x.toInt();
}

其中,
i
的声明或定义需要出现在上述定义之前,因为
i
不依赖于模板参数
T
,因此在定义点受到约束。目前未知类型
x
变量的
toInt
成员的定义只需出现在
addInt
函数实际用于某个位置之前,因为它是一个从属名称(从技术上讲,实例化点被视为使用点之前最近的封闭全局范围或命名空间范围,因此必须在使用点之前可用)。

依赖名称的特征是对模板参数的依赖关系。简单示例:

#include <vector>

void NonDependent()
{
  //You can access the member size_type directly.
  //This is precisely specified as a vector of ints.

  typedef std::vector<int> IntVector;  
  IntVector::size_type i;

  /* ... */
}

template <class T>
void Dependent()
{

  //Now the vector depends on the type T. 
  //Need to use typename to access a dependent name.

  typedef std::vector<T> SomeVector;
  typename SomeVector::size_type i;

  /* ... */
}

int main()
{
  NonDependent();
  Dependent<int>();
  return 0;
}
或使用声明放置

template <class T>
class OtherDependent : public Dependent<T>
{
    using Dependent<T>::data; //Ok now.
    ....
};
模板
类OtherDependent:公共相关
{
使用Dependent::data;//现在确定。
....
};

我要指出的是,许多编译器似乎没有强制执行依赖名称规则,但一旦你违反了该规则,你最终需要做的事情可能会有很大的变化,以使事情正常运行。我过去也因此遇到过大的问题——几乎要扔掉它,重新做大。我认为写porta很烦人BLE代码和有关代码已经在Borland C++ 5中使用,然后在出现问题之前使用了两个(也许三个)版本的VC++。基本上,谨防。我认为在结尾处的“技术”注释不是正确的,而是误导的。“技术上的”,ToTin是x类型(参数到ADDIT)的成员函数。,因此它必须在该类中声明,该类可能位于或不位于“从使用点到最近的全局或命名空间范围”:
命名空间A{struct B{int toInt();};}void f(){A::B;addInt(B);}
@dribeas:你说得很对。我写了一些与我当时想法不同的东西!我编辑了答案,以澄清封闭的名称空间与“实例化点”的含义相关例如,实际使用点稍早。谢谢。我仍然会删除名称空间部分。在使用模板之前,依赖名称必须可用。在您的特定示例中,如果依赖名称是成员函数,则名称空间不受影响,则可以在任何其他名称空间中定义该类(如果变量定义是限定的)。即使您没有一个成员,而是有一个自由函数,ADL也会启动,它会在最接近x类型的名称空间中搜索,而不是模板的实例化点。@dribeas:我现在不太明白。名称空间部分只是为了指出实例化点和使用点之间的细微差别i、 e如果我在某个其他类的成员中调用
addInt
,那么
addInt
的实例化点就不在该类的成员的使用点上,而在您自然期望的位置。这是为了防止从该成员中获取依赖名称的绑定。如果
toInt
是普通函数然后在任何本地定义的
toInt
函数上(即在该成员内定义)将被忽略。您应该明确说明“typename”是必需的,因为从属名称是类型而不是静态变量。对于非类型的从属名称,“typename”将不必。是的,这是从属名称的一个示例。事实上,我看到许多开头都被混淆了。我还用另一种情况编辑了文章关于依赖名称,我认为这种情况经常发生。+1:我从来没有意识到第二个例子是由于名称被归类为不依赖。将
使用dependent::data
放在
OtherDependent
定义上也会起到作用。@LeandroT.C.Melo不应该
name
“编译器不会在”be
数据中查找名称”
?另请参见
std::cout << "T: " << this->data << std::endl; //Ok now.
std::cout << "T: " << Dependent<T>::data << std::endl; //Ok now.
template <class T>
class OtherDependent : public Dependent<T>
{
    using Dependent<T>::data; //Ok now.
    ....
};