views:

84

answers:

3

Hi,

I'd like to build something like this:

File 1:
template<typename Vector>
namespace myNamespace {
  class myClass1{ myClass1(Vector v) {...} }
}

File 2:
template<typename Vector>
namespace myNamespace {
  class myClass2{ myClass2(Vector v) {...} }
}

Of course this is not possible because you cannot template namespaces. Instead I could use a struct instead of a namespace, but then I cannot spread the namespace functions over several files.

Is there any solution for such a problem?

PS: I know I could template the classes, but then I'd have to specify which vector type I want to use anytime I create a new class.

+3  A: 

Following up on your comment:

Instead of writing

using namespace myNamespace<int>;

Just use templated classes and write this instead (or whatever variation):

typedef myNamespace::myClass1<int> myClass1Int;
typedef myNamespace::myClass2<int> myClass2Int;

I tend to think it's better to be explicit about what types are being used rather than trying to do something like import a particular instantiation of a namespace.

Can you more fully describe the problem that makes you think templated namespaces would be useful?

And remember you can always write a make_myClass1 free function to deduce the template type for you.

Mark B
Probably a good idea.
Manuel
+1  A: 

You cannot do that, but you can provide different namespaces and typedefs (not that I endorse it).

namespace template_impl {
   template <typename V>
   class myClass1_tmpl {...};
   template <typename V>
   class myClass2_tmpl {...};
}
namespace myns_Vector1 {
   typedef ::template_impl::myClass1_tmpl<Vector1> myClass1;
   typedef ::template_impl::myClass2_tmpl<Vector1> myClass2;
}
void foo() {
   using namespace myns_Vector1;
   myClass1 mc1;
}
David Rodríguez - dribeas
A: 

Anyway, my classes have several template parameters. Now I created this approach:

#include <string>
#include <iostream>

namespace myNamespace {
  template<typename _integer, typename _string>
  struct s {
    typedef _integer integer;
    typedef _string string;
  };

  template<class T>
  class classA {
  public:
    static typename T::integer intFunc() { return 1; }
    static typename T::string stringFunc() { return "hallo"; }
  };
}


int main() {
  using namespace myNamespace;

  typedef s<int, std::string> types1;
  typedef s<unsigned int, char*> types2;

  std::cout << classA<types1>::intFunc() << std::endl;
  std::cout << classA<types1>::stringFunc() << std::endl;

  std::cout << classA<types2>::intFunc() << std::endl;
  std::cout << classA<types2>::stringFunc() << std::endl;

}

and I think I'll combine it with Mark B's approach!

Cheers, guys!

Manuel