C ++的双冒号在类名之后而不是名称空间中使用

时间:2019-07-01 12:26:34

标签: c++ syntax

我试图理解列出的here的C ++程序。我对第86-87行的双冒号的第二次使用感到困惑:

 using TransformType = itk::AffineTransform< ScalarType, Dimension >;
 TransformType::Pointer transform = TransformType::New();

看起来TransformType是用户定义的类型。在New()之前如何使用它?我听说要在名称空间后使用双冒号,但是在这里,TransformType是类型(即类)而不是名称空间。有人可以澄清---应该在C ++中的命名空间之后始终使用双冒号吗?可以使用点(例如Java)代替吗?

1 个答案:

答案 0 :(得分:5)

您可以使用范围解析运算符(::)在名称空间,类,范围枚举中命名;这称为qualified lookup

#include <iostream>

namespace N
{
   int x = 0;
}

int main()
{
   std::cout << N::x << '\n';
}

将其与类一起使用通常意味着您要引用某个static成员,因为否则通常会使用objectInstance.member

#include <iostream>

class C
{
public:
   static int x;
}

int C::x = 0;

int main()
{
   std::cout << C::x << '\n';
}

尽管,在非静态成员函数中,::仍然有用法,例如消除同时存在于不同基础中的名称之间的歧义。

class Base
{
public:
   void foo() {}
};

class Derived : public Base
{
public:
   void foo()
   {
      // Do base version (omitting Base:: will just call this one again!)
      Base::foo();

      // Now maybe do other things too
   }
};

int main()
{
   Derived obj;
   obj.foo();
}

…或用于在不需要对象上下文的情况下命名非static成员:

#include <iostream>

class C
{
public:
   int x;
}

int main()
{
    std::cout << sizeof(C::x) << '\n';

    decltype(C::x) y = 42;
}

范围内的枚举是必需的,因为它们是范围内的;这就是他们的重点。它们不会泄漏到周围的范围内,但是有它们自己的范围,因此您需要专门指定它们。

enum class E
{
   Alpha,
   Bravo,
   Charlie
};

void foo(E value) {}

int main()
{
   foo(E::Alpha);
}

某些语言允许您访问类型名称后跟static的{​​{1}}类成员,就像您访问对象名称后跟对象名称的非.类的成员一样static。 C ++不是这些语言之一。

顺便说一句,这是合法的:

.

这里不必向#include <iostream> class C { public: int x = 42; }; int main() { C obj; std::cout << obj.C::x << '\n'; // ^^^ what?! } 添加范围解析,因为该语言已经从x得知您正在请求类obj.的成员。但是您仍然可以根据需要添加它。在这种情况下,通常只是“为您完成”。