简体   繁体   中英

namespace specialization in template class

I have two different namespaces that implement identical methods and classes in two different ways. I am writing a class that used this methods and classes to do something, I was wondering if there was a way to declare the namespace without partial specialization as below:

#include <string>
#include <iostream>

namespace one
{
int test()
{
    return 1;
}
}

namespace two
{
int test()
{
    return 2;
}
}

enum names : int
{
    first = 1,
    second = 2
};

template <names>
struct base_class;

template <>
struct base_class<names::first>
{
    using namespace ::one;
};

template <>
struct base_class<names::second>
{
    using namespace ::two;
};

template <names ns>
struct delcare_namespace : public base_class<ns>
{
    delcare_namespace()
    {
        std::cout << test() << "\n";
    }
};

for the code above, I get

test' was not declared in this scope

I was wondering if there was a way to declare the namespace

Unfortunately, I don't think it's possible inside a class/struct and inheriting it.

is there a work-around for this ?

The best I can imagine (if you can heavily modify your code) is transform your two namespaces in two different classes or structs, so the functions become methods (maybe static methods)

struct baseOne  // former namespace one
 {
   static int test ()
    { return 1; }
 };

struct baseTwo // former namespace two
 {
   static int test ()
    { return 2; }
 };

so you can pass the base class (former namespace) as template parameter and inherit from it

template <typename B>
struct foo : public B
 {
   foo ()
    { std::cout << B::test() << "\n"; }
 };

The following is a full working example

#include <string>
#include <iostream>

struct baseOne  // former namespace one
 {
   static int test ()
    { return 1; }
 };

struct baseTwo // former namespace two
 {
   static int test ()
    { return 2; }
 };

template <typename B>
struct foo : public B
 {
   foo ()
    { std::cout << B::test() << "\n"; }
 };

int main ()
 {
   foo<baseOne> f1; // print 1
   foo<baseTwo> f2; // print 2
 }

If the use of the B:: before the method names is annoying for you, you can transform the static methods inside the bases structs in ordinary methods or add directives as

using B::test;

inside foo .

using namespace is not allowed in class scope, nor is namespace alias. I don't think you can do a specialization that would somehow inject the namespace.

It's not exactly the same, but if it's an option to declare all the functions you need from that namespace in the specialization, you can make the function pointer as a member of that specialization:

template <names>
struct base_class;

template <>
struct base_class<names::first>
{
    static constexpr auto test = &one::test;
};

template <>
struct base_class<names::second>
{
    static constexpr auto test = &two::test;
};

template <names ns>
struct delcare_namespace : public base_class<ns>
{
    delcare_namespace()
    {
        std::cout << this->test() << "\n";
    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM