簡體   English   中英

如何用`decltype`和繼承規避英特爾C ++編譯器的問題?

[英]How to circumvent Intel C++ compiler's issue with `decltype` and inheritance?

今天我非常驚訝地發現英特爾的icpc (版本14.0.2,使用std=c++0x )無法編譯以下代碼段。


#include <type_traits>

namespace traits_tests {
  template<typename>
  struct sfinae_true : std::true_type {};

  template<typename T>
  static auto value_type(int) -> sfinae_true<typename T::value_type>;
  template<typename T>
  static auto value_type(void*) -> std::false_type;
}

template<typename C>
struct has_value_type
  : decltype(traits_tests::value_type<C>(0)) {};

抱怨最后一行:

inc/traits.h(258): error: expected an identifier
    : decltype(traits_tests::value_type<C>(0)) {};
      ^

代碼適用於clanggcc

我真的不想完全重寫,以使它與有缺陷的編譯器一起工作(為什么商業編譯器總是有缺陷?)。

  • 是否有一種比完全不同的SFINAE模式更簡單的方法,使其與icc

編輯 :是的,我知道icc支持decltype一段時間了。 但在上面的特定背景下, icc無法支持它。 另請注意,使用std=c++11而不是std=c++0x沒有區別。

正如問題和評論中所述, decltype已經在icc了一段時間的支持; 問題是它在每個上下文中都不可用,因為編譯器中有一個令人討厭的錯誤。


更具體地說,在指定類的基礎時不能直接使用它,這需要我們編寫一個變通方法。

如果我們不能直接使用它,讓我們間接使用它(通過別名模板 )!


示例替代方法

template<class T>
using identity_hack = T;

template<typename C>
struct has_value_type
  : identity_hack<decltype (traits_tests::value_type<C> (0))>
{ }

注意:上面有很多變化,例如std::enable_if<true, decltype (...)>::type如果一個人不想聲明自己的東西,可以使用std::enable_if<true, decltype (...)>::type作為替代。

您可以使用基於模板的變通方法 - 任何采用模板類型參數的標准類型並將其作為typedef公開,然后將其包裝在僅為ICC定義的宏中,例如

#ifdef __INTEL_COMPILER
#include <utility>
#define decltype(...) \
  std::pair<decltype(__VA_ARGS__), int>::first_type
#endif

這允許您的示例編譯而無需更改。

一旦在您使用的所有ICC版本中修復了錯誤,您就可以刪除宏定義而無需更改任何其他代碼。

(參見類似MSVC問題的答案

暫無
暫無

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

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