使用enable_if选择特征-适用于clang,但不适用于gcc

旅鼠

我的工作的通用片(C ++ 11)代码的是应该与工作boost::multi_arrayEigen::Matrix和n维阵列中的,可能是其它类型的。在某些时候,我需要访问给定数组类型的元素类型。Boost数组包含一个称为typedef的数组Element,而Eigen数组包含一个称为typedef的数组Scalar

我想要的是一种类型特征,它返回给定数组类型的元素类型。不幸的是,我不能仅仅针对所有可能的数组类型对特征类进行模板化处理,因为Eigen使用表达式模板,因此,存在无限多种类型的Eigen矩阵。因此,我将SFINAE与enable_if结合使用以实现我的特征。enable_if应该选择的标准是,一个类型的typedef是Element还是Scalar

为此,我实现了type-traitshas_elementhas_scalar,它们确定相应的typedef是否存在。我的实现受到此博客文章中有关类型要求的启发

template <class T>
using ToVoid = void;

template <class T, class Enable = void>
struct has_scalar : public std::false_type {};

template <class T>
struct has_scalar<T, ToVoid<typename T::Scalar>> : public std::true_type {};

template <class T, class Enable = void>
struct has_element : public std::false_type {};

template <class T>
struct has_element<T, ToVoid<typename T::Element>> : public std::true_type {};

这样的想法是,false_type如果未显示typedef ,则编译器将选择版本,而如果存在typedef ,则编译器将选择更专业的 true_type版本。

获取标量类型的实际特征是这样实现的:

template <class Condition, class T = void>
using EnableIf = typename std::enable_if<Condition::value, T>::type;

template <class T, class Enable = void>
struct scalar_of;

template <class T>
struct scalar_of<T, EnableIf<has_element<T>>> {
    using type = typename T::Element;
};

template <class T>
struct scalar_of<T, EnableIf<has_scalar<T>>> {
    using type = typename T::Scalar;
};

template <class T>
using ScalarOf = typename scalar_of<T>::type;

一个简单的示例用例是这样的:

struct BoostArray {
    using Element = double;
};

struct EigenArray {
    using Scalar = float;
};


int main() {
    using std::is_same;
    assert((is_same<double, ScalarOf<BoostArray>>::value));
    assert((is_same<float, ScalarOf<EigenArray>>::value));
}

现在,奇怪的是,这在Clang 3.4中也能正常工作。但是,GCC 4.8.1无法对此进行编译,并给出以下错误消息:

test.cpp: In substitution of ‘template<class T> using ScalarOf = typename scalar_of<T>::type [with T = BoostArray]’:
test.cpp:51:5:   required from here
test.cpp:37:45: error: ambiguous class template instantiation for ‘struct scalar_of<BoostArray, void>’
 using ScalarOf = typename scalar_of<T>::type;
                                             ^
test.cpp:27:8: error: candidates are: struct scalar_of<T, typename std::enable_if<has_element<T, void>::value, void>::type>
 struct scalar_of<T, EnableIf<has_element<T>>> {
        ^
test.cpp:32:8: error:                 struct scalar_of<T, typename std::enable_if<has_scalar<T, void>::value, void>::type>
 struct scalar_of<T, EnableIf<has_scalar<T>>> {

lang版本在这里并且可以正常工作。gcc版本在这里,无法编译。


我的问题:我的代码是否正确,这是GCC 4.8.1的问题;还是我做错了什么,而Clang在编译时过于慷慨?无论如何,如何更改我的代码以使GCC 4.8.1可以对其进行编译?

TC

看起来这CWG第1558期又一个体现该标准尚不清楚别名模板中未使用的模板参数是否会导致替换失败。Clang将其视为替换失败;GCC只会忽略未使用的参数。

使用

template<typename... Ts>
struct make_void { typedef void type;};

template<typename... Ts>
using ToVoid = typename make_void<Ts...>::type;

相反,您应该看到它在两个编译器中都可以编译

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

熊猫groupby适用于系列,但不适用于选择整个数据框

来自分类Dev

使用LIKE运算符:适用于SQL Server,但不适用于SQLite

来自分类Dev

Javascript getElementById()适用于文本框,但不适用于单选按钮或下拉选择器

来自分类Dev

Javascript getElementById()适用于文本框,但不适用于单选按钮或下拉选择器

来自分类Dev

AJax不适用于引导选择

来自分类Dev

SQL选择不适用于哈希

来自分类Dev

IF语句问题不适用于选择

来自分类Dev

XPath不适用于XML选择

来自分类Dev

用户选择不适用于 a:visited

来自分类Dev

serializeArray 不适用于选择框

来自分类Dev

使用0.9.5.RC4的Karate.toMap()适用于方案,但不适用于方案大纲

来自分类Dev

相同的程序适用于 C,但不适用于 C++(使用 linux 系统调用)

来自分类Dev

使用@WithMockUser 的放心测试适用于 GET 请求,但不适用于 POST(403 错误)

来自分类Dev

模板的typedef包括char [] []-与VS2008一起使用,但不适用于gcc

来自分类Dev

.click()使用document.getElementById,但不适用于jquery选择器

来自分类Dev

$(this)选择器可在jsfiddle中使用,但不适用于我的脚本

来自分类Dev

相同的选择可在控制台上使用,但不适用于PHP

来自分类Dev

$(this)选择器可在jsfiddle中使用,但不适用于我的脚本

来自分类Dev

无法选择值-错误“选择仅适用于<select>元素,不适用于<a>”

来自分类Dev

ul 选择器有效,但不适用于 ul 的类

来自分类Dev

jQuery选择器不适用于类,但适用于标签

来自分类Dev

为什么图例选择仅适用于“ ax.twinx()”而不适用于“ ax”?

来自分类Dev

jQuery选择不适用于addClass,但适用于hasClass

来自分类Dev

Haskell,函数在使用数字时有效,但不适用于变量

来自分类Dev

RelativeLayout中的layout_marginRight可在Android 17上使用,但不适用于22

来自分类Dev

MySQL查询可在PHPMyAdmin中使用,但不适用于PHP

来自分类常见问题

动画屏幕可在手机上使用,但不适用于平板电脑

来自分类Dev

webgl照明着色器与Firefox一起使用,但不适用于chrome

来自分类Dev

websocket与http模块一起使用,但不适用于express(node.js)

Related 相关文章

  1. 1

    熊猫groupby适用于系列,但不适用于选择整个数据框

  2. 2

    使用LIKE运算符:适用于SQL Server,但不适用于SQLite

  3. 3

    Javascript getElementById()适用于文本框,但不适用于单选按钮或下拉选择器

  4. 4

    Javascript getElementById()适用于文本框,但不适用于单选按钮或下拉选择器

  5. 5

    AJax不适用于引导选择

  6. 6

    SQL选择不适用于哈希

  7. 7

    IF语句问题不适用于选择

  8. 8

    XPath不适用于XML选择

  9. 9

    用户选择不适用于 a:visited

  10. 10

    serializeArray 不适用于选择框

  11. 11

    使用0.9.5.RC4的Karate.toMap()适用于方案,但不适用于方案大纲

  12. 12

    相同的程序适用于 C,但不适用于 C++(使用 linux 系统调用)

  13. 13

    使用@WithMockUser 的放心测试适用于 GET 请求,但不适用于 POST(403 错误)

  14. 14

    模板的typedef包括char [] []-与VS2008一起使用,但不适用于gcc

  15. 15

    .click()使用document.getElementById,但不适用于jquery选择器

  16. 16

    $(this)选择器可在jsfiddle中使用,但不适用于我的脚本

  17. 17

    相同的选择可在控制台上使用,但不适用于PHP

  18. 18

    $(this)选择器可在jsfiddle中使用,但不适用于我的脚本

  19. 19

    无法选择值-错误“选择仅适用于<select>元素,不适用于<a>”

  20. 20

    ul 选择器有效,但不适用于 ul 的类

  21. 21

    jQuery选择器不适用于类,但适用于标签

  22. 22

    为什么图例选择仅适用于“ ax.twinx()”而不适用于“ ax”?

  23. 23

    jQuery选择不适用于addClass,但适用于hasClass

  24. 24

    Haskell,函数在使用数字时有效,但不适用于变量

  25. 25

    RelativeLayout中的layout_marginRight可在Android 17上使用,但不适用于22

  26. 26

    MySQL查询可在PHPMyAdmin中使用,但不适用于PHP

  27. 27

    动画屏幕可在手机上使用,但不适用于平板电脑

  28. 28

    webgl照明着色器与Firefox一起使用,但不适用于chrome

  29. 29

    websocket与http模块一起使用,但不适用于express(node.js)

热门标签

归档