Reputation: 10204
I am trying to understand a c++ program listed here. I am confused about the second use of double colons on lines 86-87:
using TransformType = itk::AffineTransform< ScalarType, Dimension >;
TransformType::Pointer transform = TransformType::New();
It looks like TransformType
is a user-defined type. How would one use it before New()
? I heard that the double-colon is to be used following a namespace, but here, TransformType is a type (namely class) rather than a namespace. Can someone clarify --- should double colon be always used after a namespace in C++? Would it possible to use a dot (like in Java) instead?
Upvotes: 3
Views: 1090
Reputation: 385325
You use the scope resolution operator (::
) to name something in a namespace, or in a class, or in a scoped enum; this is called qualified lookup.
#include <iostream>
namespace N
{
int x = 0;
}
int main()
{
std::cout << N::x << '\n';
}
Using it with a class usually means you're referring to some static
member, because otherwise you'd generally be using objectInstance.member
instead.
#include <iostream>
class C
{
public:
static int x;
}
int C::x = 0;
int main()
{
std::cout << C::x << '\n';
}
Though, within a non-static member function, there are still uses for ::
, such as disambiguating between names that exist concurrently in different bases.
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();
}
… or for naming a non-static
member in a scenario where an object context is not required:
#include <iostream>
class C
{
public:
int x;
}
int main()
{
std::cout << sizeof(C::x) << '\n';
decltype(C::x) y = 42;
}
It's needed with scoped enums because, well, they're scoped; that's the whole point of them. They don't leak into the surrounding scope but have their own which as a result you need to specify specifically.
enum class E
{
Alpha,
Bravo,
Charlie
};
void foo(E value) {}
int main()
{
foo(E::Alpha);
}
Some languages let you access static
members of classes with the type name followed by .
, just like you'd access non-static
members of classes with the object name followed by .
. C++ is not one of those languages.
By the way, this is legal:
#include <iostream>
class C
{
public:
int x = 42;
};
int main()
{
C obj;
std::cout << obj.C::x << '\n';
// ^^^ what?!
}
Adding scope resolution to x
here is not necessary, because the language already knows from the obj.
that you're asking for a member of a class C
. But you can still add it if you want. It's just usually "done for you" in this case.
Upvotes: 7