【问题标题】:Parameter pack expansion in a lambda with Visual Studio 2015: error C3546使用 Visual Studio 2015 在 lambda 中扩展参数包:错误 C3546
【发布时间】:2017-01-18 10:12:00
【问题描述】:

按照this question,我尝试编译以下代码:

template<typename... Types>
auto for_each(type_list<Types...>) {
    return [](auto&& f) {
        using swallow = int[];
        (void) swallow { 0, (void(f(tag<Types>{})), 0)... };
    };
}

这适用于 gcc,但使用 Visual Studio 2015 会产生以下错误:

main.cpp(19): error C3546: '...': there are no parameter packs available to expand

main.cpp(48): note: see reference to function template instantiation 'auto for_each::<lambda_9a452bac795593df4639d6433fa242d3>::operator ()<main::<lambda_b7b233027d9428cb5ddc16c87ea59d21>>(main::<lambda_b7b233027d9428cb5ddc16c87ea59d21> &&) const' being compiled

main.cpp(18): error C3520: 'Types': parameter pack must be expanded in this context

main.cpp(18): error C2672: 'operator __surrogate_func': no matching overloaded function found

main.cpp(18): error C2893: Failed to specialize function template 'auto main::<lambda_b7b233027d9428cb5ddc16c87ea59d21>::operator ()(_T1) const'

main.cpp(18): note: With the following template arguments:

main.cpp(18): note: '_T1=tag<Types>'

当符号 ... 未绑定到参数包时,看起来可视编译器无法扩展(?)

有没有办法解决这个问题?

这是一个生成错误的最小示例:

#include <iostream>
#include <string>

template<typename... > struct type_list {};

template<typename T>
struct tag { using type = T; };

template<typename... Types>
auto for_each(type_list<Types...>) {
    return [](auto&& f) {
        using swallow = int[];
        (void) swallow { 0, (void(f(tag<Types>{})), 0)... };
    };
}

struct A {
    static std::string get_type_name() { return { "A" }; }
};

struct AA : A {
    static std::string get_type_name() { return { "AA" }; }
};

int main() {
    for_each(type_list<A, AA>{}) (
        [&](auto t) {
            using B = typename decltype(t)::type;
            std::cout << B::get_type_name() << std::endl;
        }
    );

    return 0;
}

【问题讨论】:

  • 我认为这段代码格式不正确,因为auto &amp;&amp;f 不能是重载函数,而您却照样使用它。
  • @dani 嗯?我不跟随。在示例中,f 是一个 lambda。
  • 胡闹,尝试捕获type_list?
  • @Yakk 你什么意思?在 for_each 的声明中的 lambda 中捕获 type_list
  • @是的。 Eother 显式或隐式。 Dount 会起作用,但我会尝试。另一种方法可能是捕获类型标签的元组,然后使用辅助函数对象来扩展它。或者只是在具有显式 &lt;Types...&gt; 的辅助函数对象中完成您的任务。

标签: c++ visual-c++ c++14


【解决方案1】:

我最终用一个结构替换了for_each 函数:

template<typename T> struct for_each {};

template<typename... Types>
struct for_each<type_list<Types...>> {
    template<typename F>
    for_each(F f) {
        using swallow = int[];
        (void) swallow { 0, (f(tag<Types>{}), 0)... };
    }
};

稍微修改一下用法:

int main() {
    for_each<type_list<A, AA>>{
        [&](auto t) {
            using B = typename decltype(t)::type;
            std::cout << B::get_type_name() << std::endl;
        }
    };

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-11
    • 1970-01-01
    相关资源
    最近更新 更多