我今天非常惊讶地发现 Intel 的 icpc(版本 14.0.2,使用 std=c++0x
)无法编译以下代码段。 p>
#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
一起工作?
编辑:是的,我知道 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
如果不想声明自己的东西,可以作为替代方案。
关于c++ - 如何规避 Intel C++ 编译器的 `decltype` 和继承问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23951704/