繁体   English   中英

如何检查类是否具有特定功能以避免编译时问题?

[英]How to check if a class has specific function to avoid compile time issues?

我有两个类 A 和 B,有一个共同的函数对它们进行一些操作,只有很小的区别。

我尝试使用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();
    }
}

如何应对这种情况?

如果你可以使用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
}

在 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);
}

如果您有多个具有aSpecificFunctionToA类(好吧,在这种情况下,名称选择不当)您可以使用 SFINAE。

完整的 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{});
}

我更喜欢简单的老式解决方案:

#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();
}

https://godbolt.org/z/brPGr6

此代码阻止编译器基于 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM