开发者

C++ - The right way of type rebinding-resolving?

i have the following code snippets:

namespace X86X64
{
   struct IMM8 {};
}

namespace X86
{
    using namespace X86X64;

    struct RM8 {};

    template <class _Traits>
    struct MOV_Instruction
    {
        typedef typename _Traits::RM8 RM8;

        void mov(const RM8& rm, const IMM8& imm)
        {}
    };
}

namespace X64
{
  using namespace X86X64;

  struct RM8 {};
  struct RM64 {};

  struct Traits
  {
    typedef RM8 RM8;
  };

  struct MOV_Instruction : public X86::MOV_Instruction<Traits>
  {
     using X86::MOV_Instruction<Traits>::mov;

     void mov(const RM64& rm, const IMM8& imm)
     {}
  };
}

When i use no traits, i get an error, that the compiler cannot find any operator converting an X64::RM8 to X86::RM8, when instantiating MOV_Instruction.

The namespaces X86 and X64 must have their own seperate RM8 types with different underlying base types.

I wanna only use an:

using namespace X86 | X64

MOV_Instruction i;
i.mov(RM8(), IMM8());

and want the compiler to select the right RM8 type depending on the used namespace and Koenig lookup. Is their a better way to do this without a trai开发者_高级运维ts to rebind or resolve the right type?

I could make X86::RM8 and X64::RM8 the same type, but i don't wanna strive for that.

Thanks Martin


This compiles fine using VC9: 

namespace X86X64 {
    struct IMM8 {};
}

namespace X86 {
    using namespace X86X64;

    struct RM8 {};

    template <class Traits>
    struct MOV_Instruction {
        typedef typename Traits::RM8 RM8;
        void mov(const RM8& rm, const IMM8& imm) {}
    };
}

namespace X64 {
    using namespace X86X64;

    struct RM8 {};
    struct RM64 {};

    struct Traits {
        typedef RM8 RM8;
    };

    struct MOV_Instruction : public X86::MOV_Instruction<Traits> {
        using X86::MOV_Instruction<Traits>::mov;
        void mov(const RM64& rm, const IMM8& imm) {}
    };
}

int main()
{
    //using namespace X86; 
    using namespace X64;

    MOV_Instruction i;
    i.mov(RM8(), IMM8());

    return 0;
}

Note that can't have both using directives, since that would make MOV_Instruction ambiguous.

Also, I changed _Traits to Traits, since identifiers starting with an underscore, followed by a capital letter, are reserved to the implementation. (You might attract a macro from some header to trample over your code and cause very strange compiler errors.)


One more way

namespace X86X64
{
   struct IMM8 {};
}

namespace X86 { using namespace X86X64; typedef struct RM8 {} RM8;

template < class T = RM8 >
struct MOV_Instruction
{
    typedef T RM8;

    void mov(const RM8& rm, const IMM8& imm)
    {}
};

}

namespace X64 { using namespace X86X64;

typedef struct RM8 {} RM8; struct RM64 {};

template < class T = RM8 > struct MOV_Instruction : public X86::MOV_Instruction { using X86::MOV_Instruction::mov;

 void mov(const RM64& rm, const IMM8& imm)
 {}

}; }

int main() { using namespace X86;

MOV_Instruction<> i; i.mov(RM8(), IMM8()); return 0;

}

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜