如何规避英特尔C++编译器的"decltype"和继承问题?
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)) {};
^
代码在clang
和gcc
下工作良好。
我真的不喜欢完全重写以使它在有缺陷的编译器中工作(为什么商业编译器总是有缺陷?)
- 是否有一种更简单的方法,而不是完全不同的SFINAE模式,使其与
icc
一起工作?
EDIT:是的,我知道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
作为替代
您可以使用基于模板的解决方案-任何标准类型,接受模板类型参数并将其暴露为typedef
,然后将其包装在仅为ICC定义的宏中,例如
#ifdef __INTEL_COMPILER
#include <utility>
#define decltype(...)
std::pair<decltype(__VA_ARGS__), int>::first_type
#endif
允许您的示例编译而无需更改。
一旦你使用的所有版本的ICC的错误被修复,你可以删除宏定义而不改变任何其他代码。
(参见对类似MSVC问题的回答)
相关文章:
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 使用具有默认参数的函数模板进行 decltype 会使结果混乱(一个有趣的问题或 gcc 的错误)
- decltype和模板的问题
- 有关 const decltype(x)& 的问题
- c++ 11 -使用decltype函数指针有什么问题?
- 如何规避英特尔C++编译器的"decltype"和继承问题?
- decltype的另一个问题