簡體   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