lambdas中的跨平台“auto”关键字用法:integral_constant作为函数参数

时间:2017-09-12 10:10:01

标签: c++ lambda c++14

我开发了一个跨平台(Linux和Win)库。在其中我使用以下辅助模板化函数来处理元组(例如):

#include <iostream>
#include <string>
#include <tuple>
#include <utility>
#include <type_traits>

using namespace std;

template <class F, size_t... Is>
constexpr void index_apply_impl1(const F &f,
                                const index_sequence<Is...>&) {
    int d[] = { 0, (f(integral_constant<size_t, Is> {}), 0)... };
}

template <size_t N, class F>
constexpr void index_apply1(const F& f) {
    index_apply_impl1(f, make_index_sequence<N>{});
}

template <class Tuple, class F>
constexpr void apply1(const Tuple &t, const F &f) {
    index_apply1<tuple_size<Tuple>{}>(
        [&](auto &Is) { f(get<Is>(t)); } );
}

template <size_t N, class F>
constexpr void apply_by_index1(const F &f) {
    index_apply1<N>(
        [&](auto &&Is) { f(integral_constant<size_t, Is> {}); });
}

int main() {
    auto t = make_tuple("aaa", 1, 11.11);

    // does not work with gcc too
    //apply1(t, [&](auto &v) { cout << v << endl;} );

    apply_by_index1<tuple_size<decltype(t)>::value>([&](auto &&i) { cout << get<i>(t) << endl; });
}

此代码已成功编译并按预期使用GCC 5.4和6.4,但不会使用MS Build tools 2015进行编译(MS VC ++ 2017版本尚未检查)。 VC ++编译器打印的错误与 函数“apply_by_index1”中的lambdas的“auto”-type参数“Is”。 VC ++说:

zz.cpp(29):错误C2975:'_ VAL':'std :: integral_constant'的模板参数无效,预期的编译时常量表达式

...

zz.cpp(38):错误C2672:'get':找不到匹配的重载函数 zz.cpp(29):注意:参见函数模板实例化'auto main :::: operator()&gt;(std :: integral_constant&amp;&amp;)const'正在编译

zz.cpp(38):错误C2975:'_ Idx':'std :: get'的模板参数无效,是预期的编译时常量表达式

......等等

通常可以用VC ++实现这样的功能还是我错过了什么?我的想法是用functor替换lambdas,但我仍然不知道如何实现它(我不是专业程序员)

我没有Clang / llvm,但我相信这段代码应该由版本&gt; = 4的Clang编译。正确?

1 个答案:

答案 0 :(得分:0)

我可以给你至少部分解决方案。你仍然不能在lambda中使用std :: get。

/