Following this question , I tried to compile the following code:
template<typename... Types>
auto for_each(type_list<Types...>) {
return [](auto&& f) {
using swallow = int[];
(void) swallow { 0, (void(f(tag<Types>{})), 0)... };
};
}
This works fine with gcc, but generates the following error with 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>'
It seems that the visual compiler does not work with the extension if the character is ...not tied to a parameter package (?)
Is there any way to solve the problem?
Here is a minimal example for generating an error:
#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;
}
source
share