【发布时间】: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 &&f不能是重载函数,而您却照样使用它。 -
@dani 嗯?我不跟随。在示例中,
f是一个 lambda。 -
胡闹,尝试捕获
type_list? -
@Yakk 你什么意思?在
for_each的声明中的 lambda 中捕获type_list? -
@是的。 Eother 显式或隐式。 Dount 会起作用,但我会尝试。另一种方法可能是捕获类型标签的元组,然后使用辅助函数对象来扩展它。或者只是在具有显式
<Types...>的辅助函数对象中完成您的任务。
标签: c++ visual-c++ c++14