簡體   English   中英

編譯時檢查輸出(<<)和關系(<,>等)是否可用

[英]Compile-time check whether output (<<) and relational (<, >, etc.) are available

我目前正在使用is_call_possible第三方代碼

https://github.com/jaredhoberock/is_call_possible

如果一個成員可用,在編譯時弄清楚。 這個例子效果很好:

#include <string>
#include "is_call_possible.h"

DEFINE_IS_CALL_POSSIBLE(is_call_possible, operator())
DEFINE_IS_CALL_POSSIBLE(test_available, test)

struct Foo {
  void operator()(double) {}
  double test(std::string) { return 0; }
};

int main(int argc, const char * argv[]) {
  static_assert(is_call_possible<Foo, void(double)>::value,"err"); //success
  static_assert(test_available<Foo, double(std::string)>::value,"err"); //success
  return 0;
}

但這對普通的非成員不起作用,所以我不能對輸出和關系運算符做同樣的事情:

DEFINE_IS_CALL_POSSIBLE(output_available, operator<<) //error
DEFINE_IS_CALL_POSSIBLE(less_available, operator<) //error
DEFINE_IS_CALL_POSSIBLE(greater_available, operator>) //error

你能指點我方便的第三方代碼(或你自己的代碼)來容納這個嗎?

底層解決方案(“第三方代碼”)可以在C ++ 11中實現,如果它更容易,但我想我不會注意到我自己的代碼(作為第三方代碼的用戶)的差異。

假設C ++ 11是一個選項, decltype編譯時結構可以與SFINAE一起使用,基本上對類型進行“概念檢查”(盡管在C ++ 11標准中缺乏真正的概念檢查),看看如果他們支持運營。

(未經測試,因為我現在缺少一個C ++ 11編譯器[詛咒你的Windows~!],但我確信有人會抓住我的錯誤,如果它們存在的話)。

防爆。

template<typename T> struct voidify{typedef void type;};
template<typename T, typename U, typename enable=void>
struct has_operator_less {
  enum{value=false};
};
template<typename T, typename U>
struct has_operator_less<T, U, typename voidify<decltype(
  std::declval<T>() < std::declval<U>() // <-- this is the 'concept' check
)>::type> {
  enum{value=true};
};

並且你使用它來啟用/禁用任何函數的std::enable_if構造,這取決於是否存在這兩種類型的operator< exists:

template<typename T, typename U>
typename std::enable_if<
  has_operator_less<T, U>::value, I_am_the_result_type_of_the_function
>::type
I_depend_on_the_existence_of_the_less_than_operator(const T& a, const U& b) {...}

如果你想要缺少operator<類型的函數的替代實現,你只需啟用否定:

template<typename T, typename U>
typename std::enable_if<
  !has_operator_less<T, U>::value, I_am_the_result_type_of_the_function
  // ^ note the negation
>::type
I_depend_on_the_existence_of_the_less_than_operator(const T& a, const U& b) {...}

因此,現在您已經在編譯時確定了具有不具有這些運算符的類型和類型的實現,並且可以針對任何其他運算符或函數名稱或任何您想要的內容重復此解決方案。 只需將您正在檢查的概念放在decltype

這些都不需要在構建之前進行單獨的配置步驟。

(再一次,未經測試的代碼-.-'但非常肯定是正確的;其余的都知道編輯按鈕的位置:-P)

Boost Type Traits將執行此操作。

注意:模板代碼仍然存在問題(無論您使用哪種方法來檢測它)。 例如, vector<T>::operator<假定T有一個operator< ,所以你得到以下內容:

struct Silly {};

std::cout << boost::has_less<Silly>::value << std::endl;  // 0
std::cout << boost::has_less<std::vector<Silly>>::value << std::endl;  // 1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM