将代码移出 class 定义时未扩展参数包
Parameter pack not expanded when moving code out of class definition
我有模板 class,看起来像这样:
template<typename... Args>
class Foo
{
public:
void Bar() {
(std::get<Args>(m_args).Bar(), ...);
}
private:
std::tuple<Args...> m_args;
};
下面是我的使用方式:
template<size_t I>
class Test
{
public:
void Bar() {
std::cout << I << std::endl;
}
};
int main() {
Foo<Test<0>, Test<1>> object;
object.Bar();
}
这个版本工作得很好,但我需要将方法定义移出 class 接口(以增加它的可读性)。问题是该技巧的语法是什么?
我试过这个:
template<typename... Args>
void Foo<Args...>::Bar() {
(std::get<Args>(m_args).Bar(), ...);
}
但编译失败并显示错误消息:
error C3520: 'Args': parameter pack must be expanded in this context
note: while compiling class template member function 'void Foo<Test<0>,Test<1>>::Bar(void)'
note: see reference to function template instantiation 'void Foo<Test<0>,Test<1>>::Bar(void)' being compiled
note: see reference to class template instantiation 'Foo<Test<0>,Test<1>>' being compiled
error C2228: left of '.Bar' must have class/struct/union
error C2059: syntax error: '...'
我已经在 clang 7 上检查了这段代码,它可以正常工作,所以它看起来像 MSC 编译器错误 (visual studio 15.7.1)。
这个东西看起来像 MSVC 错误,并在使用折叠表达式时重现。
所以解决方法是将代码从 C++ 17 降级到 C++ 14 并使用 'classic' initializer_list
hack:
template<typename... Args>
void Foo<Args...>::Bar() {
(void)std::initializer_list<int>{
(std::get<Args>(m_args).Bar(), 0)...
};
}
我有模板 class,看起来像这样:
template<typename... Args>
class Foo
{
public:
void Bar() {
(std::get<Args>(m_args).Bar(), ...);
}
private:
std::tuple<Args...> m_args;
};
下面是我的使用方式:
template<size_t I>
class Test
{
public:
void Bar() {
std::cout << I << std::endl;
}
};
int main() {
Foo<Test<0>, Test<1>> object;
object.Bar();
}
这个版本工作得很好,但我需要将方法定义移出 class 接口(以增加它的可读性)。问题是该技巧的语法是什么?
我试过这个:
template<typename... Args>
void Foo<Args...>::Bar() {
(std::get<Args>(m_args).Bar(), ...);
}
但编译失败并显示错误消息:
error C3520: 'Args': parameter pack must be expanded in this context
note: while compiling class template member function 'void Foo<Test<0>,Test<1>>::Bar(void)'
note: see reference to function template instantiation 'void Foo<Test<0>,Test<1>>::Bar(void)' being compiled
note: see reference to class template instantiation 'Foo<Test<0>,Test<1>>' being compiled
error C2228: left of '.Bar' must have class/struct/union
error C2059: syntax error: '...'
我已经在 clang 7 上检查了这段代码,它可以正常工作,所以它看起来像 MSC 编译器错误 (visual studio 15.7.1)。
这个东西看起来像 MSVC 错误,并在使用折叠表达式时重现。
所以解决方法是将代码从 C++ 17 降级到 C++ 14 并使用 'classic' initializer_list
hack:
template<typename... Args>
void Foo<Args...>::Bar() {
(void)std::initializer_list<int>{
(std::get<Args>(m_args).Bar(), 0)...
};
}