c++:分别处理不同的模板参数

Ame*_*nde 2 c++ c++17

我有一个程序如下(这是我实际问题的再现):

#include <iostream>

class A {
public:
    void printA () {
        std::cout << "AA" << std::endl;
    }
};

class B {
public:
    void printB () {
        std::cout << "BB" << std::endl;
    }
};

template <typename T>
class C {
public:
    void printC () {
        T obj;
        if (std::is_same<A, T>::value) {
            obj.printA ();
        } else if (std::is_same<B, T>::value) {
            obj.printB ();
        }
    }
};


int main () {
    C<A> c1;
    C<B> c2;
    c1.printC ();
    c2.printC ();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在编译时,我收到以下错误:

handle_different_typenames.cpp: In instantiation of ‘void C<T>::printC() [with T = A]’:
handle_different_typenames.cpp:34:16:   required from here
handle_different_typenames.cpp:25:17: error: ‘class A’ has no member named ‘printB’; did you mean ‘printA’?
   25 |             obj.printB ();
      |             ~~~~^~~~~~
      |             printA
handle_different_typenames.cpp: In instantiation of ‘void C<T>::printC() [with T = B]’:
handle_different_typenames.cpp:35:16:   required from here
handle_different_typenames.cpp:23:17: error: ‘class B’ has no member named ‘printA’; did you mean ‘printB’?
   23 |             obj.printA ();
      |             ~~~~^~~~~~
      |             printB
Run Code Online (Sandbox Code Playgroud)

如何解决这个问题?理想情况下,我想要的情况是,如果 T = A,则else if (std::is_same<B, T>::value) {...}不应在编译时检查内部代码。同样,如果 T = B,则if (std::is_same<A, T>::value) {...}不应在编译时检查内部代码。

提前致谢!

Aco*_*orn 6

有几种方法...

在 C++17 中,如果你只在一个地方需要它,最好的是:

template <typename T>
class C {
public:
    void printC () {
        T obj;
        if constexpr (std::is_same<A, T>::value) {
            obj.printA ();
        } else if constexpr (std::is_same<B, T>::value) {
            obj.printB ();
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

在较旧的标准中,对于这种情况,重载很容易:

void print(A& obj) { obj.printA(); }
void print(B& obj) { obj.printB(); }

template <typename T>
class C {
public:
    void printC () {
        T obj;
        print(obj);
    }
};
Run Code Online (Sandbox Code Playgroud)