C++中的模板和预处理

Val*_* T. 1 c++ enums templates if-statement c++03

如何编译此代码:

#include <iostream>
using namespace std;

enum E { A, B};

template< E x>
class C {
public:
    #if( x == A)
        static void foo() {
            cout << "A";
        }
    #elif( x == B)
        static void goo() {
            cout << "B";
        }
    #endif
};


int main() {
    C< A>::foo();
    C< B>::goo();

    return 0;
}

error: ‘goo’ is not a member of ‘C<(E)1u>’
Run Code Online (Sandbox Code Playgroud)

我有两个大的类只有几行不同,所以我想制作枚举模板.问题是这些行中有using关键字,所以我不知道该放什么.

有没有正确的方法呢?

PS>我必须使用C++ 03.

编辑:一点澄清.我知道template<>构造,但我不想使用它,因为这样我得到了很多代码重复.也许我可以以某种方式进行部分"模板实例化"(如果这是正确的术语template<>)?

假设我有两个类(我不会有更多):

class A {
public:
//…a lot of code…
//few lines that differs in A and B
}

class B {
//…the same mass of code…
//few lines that differs in A and B
}
Run Code Online (Sandbox Code Playgroud)

所以我决定制作模板enum:

enum E { A, B}
template< E>
class C{
//…common code…
}
Run Code Online (Sandbox Code Playgroud)

现在我不知道如何处理A和B中不同的几行.我知道常见的方法是进行模板实例化,但后来我会得到我对类A和文件的确切结果B.

从面向对象的时候,我应该使用共同BaseAB.但问题是,A并且B已经是相同的了.它们只与行有所不同:

using CanStoreKeyValue< QString, Request>::set;
using CanStoreKeyValue< QString, Response>::set;
Run Code Online (Sandbox Code Playgroud)

where ResponseRequest是typedef.而且,在我的代码中A,B它们是同一个模板化抽象类的子代.当然,他们使用不同的模板参数继承它.这以某种方式破坏了模板枚举的使用 - 编译器只是看不到某些虚拟方法不再纯粹.所以......这就是为什么我在问我在问什么.我认为预处理器可以使用#if-directives 与模板引擎交互(最后,它们都是编译时进程).

Sla*_*ica 5

您无法使用预处理器来实现您要执行的操作.你需要的是模板专业化:

enum E { A, B};

template< E x>
class C;

template <>
class C<A> {
public:
    static void foo() {
        cout << "A";
    }
};

template <>
class C<B> {
public:
    static void goo() {
        cout << "B";
    }
};
Run Code Online (Sandbox Code Playgroud)

您的更新问题仍然可以通过模板专业化来解决:

enum E { A, B };

template< E x >
struct CanStoreKeyValueHelper;

template<>
struct CanStoreKeyValueHelper<A> {
    typedef CanStoreKeyValue< QString, Request>::set type;
};

template<>
struct CanStoreKeyValueHelper<B> {
    typedef CanStoreKeyValue< QString, Response>::set type;
};

template< E x>
class SuperPuperBigClass {
public:
    typedef typename CanStoreKeyValueHelper<x>::type set;
    ...
};
Run Code Online (Sandbox Code Playgroud)

但目前尚不清楚为什么你不这么简单:

template<class T>
class SuperPuperBigClass {
public:
    typedef typename CanStoreKeyValue<QString, T>::set set;
};
Run Code Online (Sandbox Code Playgroud)

并使用请求和响应类型实例化它