5

Given:

namespace A {
  class Foo;
  class Bar;
}

namespace B {
  class Foo;
  class Bar;
}

I want to template a class on the namespace A or B such that the following works:

template<name> class C {
  name::Foo* foo;
  name::Bar* bar;
}

Can this be done directly or do I need to create a pair of struct types with typedefs in them?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
BCS
  • 75,627
  • 68
  • 187
  • 294

3 Answers3

4

You can't template on a namespace. If you're able to use a class (with most likely public attributes/static methods) then you can template on the class as a semi-workaround.

Mark B
  • 95,107
  • 10
  • 109
  • 188
1

No, templates can't be parametrized on a namespace.

Dr. Snoopy
  • 55,122
  • 7
  • 121
  • 140
0

With my limited knowledge, I believe that this would be a useful tool, and seems to be a relationship that could exist between namespaces and templates. Some people argue that it would be hard to implement and is unnecessary, however.

In the example above, I would use structs rather than namespaces (I use struct over class because by default its access is "public"). Below should be a fully compilable example:

#include <iostream>

// Replaces namepace 'A' from above.
templates
struct Option1 {

    class Foo;

    //Example function, too.
    void myFunc() {
        std::cout << "Hello!\n";
    }
};

// A second Option for example.
struct Option2 {
    class Foo;

    void myFunc() {
        std::cout << "Hola!!\n";
    }
};

// Can be in .cpp file
class Option1::Foo {
public:
    Foo() { display(); }

    void display() {
       std::cout << "Option 1.\n";
    }
};

class Option2::Foo {
public:
    Foo() { display(); }

    void display() {
        std::cout << "Option 2.\n";
    }
};

The template could then be as follows:

// The typename C would need class 'Foo' 
template <typename C>
class OptionSelect : public C
{
    typename C::Foo* foo;

    public:
    OptionSelect() {
        foo = new typename C::Foo();
    }

};

int main() {
    OptionSelect<Option1> opt1;
    OptionSelect<Option2> opt2;

    opt1.myFunc();  // Provided that template had myFunc
    opt2.myFunc();         

    return 0;
}

The result should be as follows when built:

Option 1.
Option 2.
Hello!
Hola!!

I got the idea of inheriting a template class from here, though I'll admit without defining myFunc() as I did, inheriting the template would be optional. The article is worth checking out. It has many useful and unconventional tricks to using templates.

Clint Chelak
  • 232
  • 2
  • 9