You cannot nest code blocks (i.e. {...}
) outside functions.
Let's say we have this part in common:
namespace A1 { namespace A2 {
class MyClass1;
}}
namespace B1 { namespace B2 {
class MyClass2;
}}
namespace A {
template<typename T>
struct C
{
static int member1_;
static int member2_;
static int member3_;
};
}
You can either import the names into namespace A
, making them available through the qualification A::
:
namespace A {
using A1::A2::MyClass1;
template <> int C<MyClass1>::member1_ = 5;
template <> int C<MyClass1>::member2_ = 5;
template <> int C<MyClass1>::member3_ = 5;
using B1::B2::MyClass2;
template <> int C<MyClass2>::member1_ = 6;
template <> int C<MyClass2>::member2_ = 6;
template <> int C<MyClass2>::member3_ = 6;
}
but I assume that is unwanted and you see this as pollution. So then the only thing you can do is use an extra namespace to decrease the number of ::
:
namespace A {
namespace T {
using T1 = A1::A2::MyClass1;
using T2 = B1::B2::MyClass2;
}
template <> int C<T::T1>::member1_ = 5;
template <> int C<T::T1>::member2_ = 5;
template <> int C<T::T1>::member3_ = 5;
template <> int C<T::T2>::member1_ = 6;
template <> int C<T::T2>::member2_ = 6;
template <> int C<T::T2>::member3_ = 6;
}
This keeps your namespace A
clear of unwanted typenames, although it introduces an "implementation namespace" T
(which is a terrible name for a namespace!!!).
A third alternative specializes struct
template C
for the types you want:
namespace A{
template<>
struct C<A1::A2::MyClass1>
{
static const int member1_ = 5;
static const int member2_ = 5;
static const int member3_ = 5;
};
template<>
struct C<B1::B2::MyClass2>
{
static const int member1_ = 5;
static const int member2_ = 5;
static const int member3_ = 5;
};
}
Note that this requires static const
data members. You can also do away with a declaration of the struct
template like so:
namespace A {
template<typename T>
struct C;
}
to limit its use (at compile time) to only the types you want. This would me my preferred solution.