[英]How to check if a class has specific function to avoid compile time issues?
I have two class A and B, with a common function doing some operation on both of them with just a minor difference.我有两个类 A 和 B,有一个共同的函数对它们进行一些操作,只有很小的区别。
I tried using std::is_same
, but looks like it won't prevent compile-time issues.我尝试使用
std::is_same
,但看起来它不会阻止编译时问题。
class A {
public:
void aSpecificFunctionToA() {
}
};
class B {
};
template<typename T>
void someFunction(T obj) {
if(std::is_same<T, A>::value)
{
obj.aSpecificFunctionToA();
}
}
How to tackle this situation?如何应对这种情况?
If you can use c++17, then you can use if constexpr
to conditionally compile code if it satisfies some constraints.如果你可以使用c++17,那么你可以使用
if constexpr
来有条件地编译代码,如果它满足一些约束。
template<typename T>
void someFunction(T obj) {
if constexpr (std::is_same<T, A>::value)
{
obj.aSpecificFunctionToA();
}
// ... code for all Ts
}
Before c++17, you can use an overload for A
, and put the code that is common to all T
s into a separate function:在 c++17 之前,您可以对
A
使用重载,并将所有T
共有的代码放入一个单独的函数中:
template<typename T>
void common_code(T obj) {
// ... code for all Ts
}
template<typename T>
void someFunction(T obj) {
common_code(obj);
}
void someFunction(A obj) {
obj.aSpecificFunctionToA();
common_code(obj);
}
If you have more than one class having aSpecificFunctionToA
(well, in this case the name is poorly choose) you can use SFINAE.如果您有多个具有
aSpecificFunctionToA
类(好吧,在这种情况下,名称选择不当)您可以使用 SFINAE。
Full C++11 :完整的 C++11 :
#include <vector>
#include <functional>
#include <iostream>
#include <memory>
#include <type_traits>
namespace detail_traits
{
template <class...>
struct Args
{
};
template <class... T>
using void_t = void;
template <class T, class args, class = void>
struct has_aSpecificFunctionToA : std::false_type
{
};
template <class T, class... args>
struct has_aSpecificFunctionToA<
T,
Args<args...>,
void_t<decltype(std::declval<T>().aSpecificFunctionToA(std::declval<args>()...))>> : std::true_type
{
};
} // namespace detail_traits
template <class T, class... Args>
using has_aSpecificFunctionToA = typename detail_traits::has_aSpecificFunctionToA<T, detail_traits::Args<Args...>>;
class A
{
public:
void aSpecificFunctionToA() {
std::cout << "aSpecificFunctionToA" << std::endl;
}
};
class B
{
};
template <typename T>
typename std::enable_if<has_aSpecificFunctionToA<T>::value>::type someFunction(T obj)
{
obj.aSpecificFunctionToA();
}
template <typename T>
typename std::enable_if<!has_aSpecificFunctionToA<T>::value>::type someFunction(T )
{
std::cout << "some code for class without aSpecificFunctionToA" << std::endl;
}
int main()
{
std::cout << has_aSpecificFunctionToA<A>::value << std::endl;
std::cout << has_aSpecificFunctionToA<B>::value << std::endl;
someFunction(A{});
someFunction(B{});
}
I prefer simple old fashion solution:我更喜欢简单的老式解决方案:
#define LOG std::cout << __PRETTY_FUNCTION__ << '\n'
class A {
public:
void aSpecificFunctionToA() {
LOG;
}
};
class B {
};
template<typename T>
void someFunction(T obj) {
LOG;
}
void someFunction(A obj) {
LOG;
obj.aSpecificFunctionToA();
}
This code prevented the compiler to build that particular if block based on a const bool expression.此代码阻止编译器基于 const bool 表达式构建特定的 if 块。
const bool flag = std::is_same<T, A>::value;
#if(flag)
{
obj.aSpecificFunctionToA();
}
#endif
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.