0

I'm writing for a project that uses makefile rules to switch between GPU and CPU implementations. I'd like to present an interface to user code that automatically switches between implementations without having to write #ifdef GPU_MODE all over the place.

My solution had been to use a templated interface class followed by alias templates (just typedefs, really, but I like the left-to-right style) like so:

namespace INTERFACE{
    template <class VERSION>
    class MyClass{
        public:
           MyClass():theClass(){};
           //more methods...
        private:
           VERSION theClass;
    };
 }
 using CpuMyClass = INTERFACE::MyClass<CpuMode>; //CpuMode defined elsewhere 
 #ifdef GPU_MODE
 using MyClass = INTERFACE::MyClass<GpuMode>;
 #else
 using MyClass = INTERFACE::MyClass<CpuMode>;
 #endif

Thus allowing outside code to use the symbol MyClass freely, trusting it to switch between modes automatically. Unfortunately using this is proving confusing. For example, I have a second class for which I'd like to write a ctor from MyClass:

#include "MyClass.hpp"
class OutsideClass{
    public:
        OutsideClass(const MyClass& A);
};

This ctor triggers an "identifier 'MyClass' is undefined" error. Does anyone know what's going on here?

AGML
  • 890
  • 6
  • 18
  • the code you have shown [does not reproduce the error](http://coliru.stacked-crooked.com/a/80bd88675e5cec7a) – sp2danny Sep 17 '15 at 23:06
  • because the question was invalidated through editing... – Naios Sep 17 '15 at 23:16
  • 1
    My guess is a circular include dependency, but there's not enough information to tell. – T.C. Sep 18 '15 at 02:35
  • The edits fixed an error in the original post which was not present in the actual code. Apologies. However as noted it seems the error is not reproduced using clang, so it is presumably caused by some relevant detail I've unknowingly excluded. – AGML Sep 18 '15 at 17:11
  • This issue was caused by a circular include dependency, as suggested (which was not present in the example code). – AGML Sep 18 '15 at 19:22

1 Answers1

1

Did you mean something like:

struct GpuMode { };
struct CpuMode { };

namespace INTERFACE {
// ~~~~~~~~^^^^^^
    template <class VERSION>
    class MyClass{

        public:
           MyClass() : theClass(){};
           //more methods..

        private:
           VERSION theClass;
    };
 }

 using CpuMyClass = INTERFACE::MyClass<CpuMode>; //CpuMode defined elsewhere 

 #ifdef GPU_MODE
   using MyClass = INTERFACE::MyClass<GpuMode>;
 #else
   using MyClass = INTERFACE::MyClass<CpuMode>;
 #endif

 class OutsideClass{
    public:
        OutsideClass(const MyClass& A);
};

Demo

Naios
  • 1,513
  • 1
  • 12
  • 26
  • I got really excited, but it turns out the brackets around the namespace were a typo only in my StackOverflow post. – AGML Sep 17 '15 at 22:55