我有一个程序如下(这是我实际问题的再现):
#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) {...}不应在编译时检查内部代码。
提前致谢!
有几种方法...
在 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)