无法使用元编程在可变参数模板中声明变量
Cannot declare a variable in a variadic template using metaprogramming
我正在使用可变参数模板函数为每个参数执行一个函数。迭代使用元编程,但有一个问题:我不能在其中声明一个简单的变量。这是一个例子:
template < size_t I = 0, typename... Args >
auto recursive_function( std::tuple< Args... > const& t )
-> typename std::enable_if< I == sizeof...(Args), void >::type
{
}
template < size_t I = 0, typename... Args >
auto recursive_function( std::tuple< Args...>const & t )
-> typename std::enable_if< I < sizeof...(Args), void >::type
{
cout << get<I>(t) << endl;
recursive_function< I + 1, Args... >( t );
}
这些函数可以很好地显示任何参数,但是如果我们稍微更改一下代码...
template < size_t I = 0, typename... Args >
auto recursive_function( std::tuple< Args... > const& t )
-> typename std::enable_if< I == sizeof...(Args), void >::type
{
}
template < size_t I = 0, typename... Args >
auto recursive_function( std::tuple< Args...>const & t )
-> typename std::enable_if< I < sizeof...(Args), void >::type
{
cout << get<I>(t) << endl;
// Just a simple declaration added...
int i = 0;
recursive_function< I + 1, Args... >( t );
}
[编辑]
编译器抱怨:
main.cpp: In instantiation of 'typename std::enable_if<(I < sizeof (Tp ...)), void>::type recursive_function(const std::tuple<_Elements ...>&) [with long unsigned int I = 0ul; Args = {int, int, int, int, int}; typename std::enable_if<(I < sizeof (Tp ...)), void>::type = void]':
main.cpp:524:31: required from here
main.cpp:511:9: warning: unused variable 'i' [-Wunused-variable]
int i=0;
^
main.cpp: In instantiation of 'typename std::enable_if<(I < sizeof (Tp ...)), void>::type recursive_function(const std::tuple<_Elements ...>&) [with long unsigned int I = 1ul; Args = {int, int, int, int, int}; typename std::enable_if<(I < sizeof (Tp ...)), void>::type = void]':
main.cpp:512:45: required from 'typename std::enable_if<(I < sizeof (Tp ...)), void>::type recursive_function(const std::tuple<_Elements ...>&) [with long unsigned int I = 0ul; Args = {int, int, int, int, int}; typename std::enable_if<(I < sizeof (Tp ...)), void>::type = void]'
main.cpp:524:31: required from here
main.cpp:511:9: warning: unused variable 'i' [-Wunused-variable]
main.cpp: In instantiation of 'typename std::enable_if<(I < sizeof (Tp ...)), void>::type recursive_function(const std::tuple<_Elements ...>&) [with long unsigned int I = 2ul; Args = {int, int, int, int, int}; typename std::enable_if<(I < sizeof (Tp ...)), void>::type = void]':
main.cpp:512:45: recursively required from 'typename std::enable_if<(I < sizeof (Tp ...)), void>::type recursive_function(const std::tuple<_Elements ...>&) [with long unsigned int I = 1ul; Args = {int, int, int, int, int}; typename std::enable_if<(I < sizeof (Tp ...)), void>::type = void]'
这只是一个示例(没有理由以这种方式声明变量...),但我想了解此错误的含义。
有人知道吗?
[EDIT2] 这是工作代码
#include <iostream>
#include <tuple>
#include <utility>
using namespace std;
template < size_t I = 0, typename... Args >
auto recursive_function( std::tuple< Args... > const& t )
-> typename std::enable_if< I == sizeof...(Args), void >::type
{
}
template < size_t I = 0, typename... Args >
auto recursive_function( std::tuple< Args...>const & t )
-> typename std::enable_if< I < sizeof...(Args), void >::type
{
cout << get<I>(t) << endl;
int i = 0;
recursive_function< I + 1, Args... >( t );
}
int main( int argc, char** argv )
{
try
{
auto t = make_tuple(1,2,3,4,5);
recursive_function( t );
}
catch( std::exception& e )
{
cerr << e.what() << endl;
}
return 0;
}
完整的错误信息在上面。
使用的编译器版本是 GCC 4.8.2,选项为 std=c++1y,我使用的是 Code::Blocks。奇怪的是,构建完成时有 2 个错误和 15 个警告,但实际输出考虑了更改(这样就没有考虑错误?)
您创建了一个变量但没有使用它。
您已启用所有警告 (-Wall
) 和错误警告。由于创建无意义的变量通常表示您犯了错误,因此编译器会发出警告。
所以一个警告(你创建了一个变量但没有使用它)产生了一个错误,然后它详细说明了这个错误是如何产生的(模板实例化将它的实例化包装为一个未使用的变量)。
在下一行插入 (void)i;
,警告消失。
请注意,warnings-as-errors 是一个很好的计划,坚持下去,同时也坚持 -Wall
(激活所有警告)。你的问题是你没有找到真正的错误是什么,你被编译器提供的模板扩展注释分散了注意力。
我正在使用可变参数模板函数为每个参数执行一个函数。迭代使用元编程,但有一个问题:我不能在其中声明一个简单的变量。这是一个例子:
template < size_t I = 0, typename... Args >
auto recursive_function( std::tuple< Args... > const& t )
-> typename std::enable_if< I == sizeof...(Args), void >::type
{
}
template < size_t I = 0, typename... Args >
auto recursive_function( std::tuple< Args...>const & t )
-> typename std::enable_if< I < sizeof...(Args), void >::type
{
cout << get<I>(t) << endl;
recursive_function< I + 1, Args... >( t );
}
这些函数可以很好地显示任何参数,但是如果我们稍微更改一下代码...
template < size_t I = 0, typename... Args >
auto recursive_function( std::tuple< Args... > const& t )
-> typename std::enable_if< I == sizeof...(Args), void >::type
{
}
template < size_t I = 0, typename... Args >
auto recursive_function( std::tuple< Args...>const & t )
-> typename std::enable_if< I < sizeof...(Args), void >::type
{
cout << get<I>(t) << endl;
// Just a simple declaration added...
int i = 0;
recursive_function< I + 1, Args... >( t );
}
[编辑] 编译器抱怨:
main.cpp: In instantiation of 'typename std::enable_if<(I < sizeof (Tp ...)), void>::type recursive_function(const std::tuple<_Elements ...>&) [with long unsigned int I = 0ul; Args = {int, int, int, int, int}; typename std::enable_if<(I < sizeof (Tp ...)), void>::type = void]':
main.cpp:524:31: required from here
main.cpp:511:9: warning: unused variable 'i' [-Wunused-variable]
int i=0;
^
main.cpp: In instantiation of 'typename std::enable_if<(I < sizeof (Tp ...)), void>::type recursive_function(const std::tuple<_Elements ...>&) [with long unsigned int I = 1ul; Args = {int, int, int, int, int}; typename std::enable_if<(I < sizeof (Tp ...)), void>::type = void]':
main.cpp:512:45: required from 'typename std::enable_if<(I < sizeof (Tp ...)), void>::type recursive_function(const std::tuple<_Elements ...>&) [with long unsigned int I = 0ul; Args = {int, int, int, int, int}; typename std::enable_if<(I < sizeof (Tp ...)), void>::type = void]'
main.cpp:524:31: required from here
main.cpp:511:9: warning: unused variable 'i' [-Wunused-variable]
main.cpp: In instantiation of 'typename std::enable_if<(I < sizeof (Tp ...)), void>::type recursive_function(const std::tuple<_Elements ...>&) [with long unsigned int I = 2ul; Args = {int, int, int, int, int}; typename std::enable_if<(I < sizeof (Tp ...)), void>::type = void]':
main.cpp:512:45: recursively required from 'typename std::enable_if<(I < sizeof (Tp ...)), void>::type recursive_function(const std::tuple<_Elements ...>&) [with long unsigned int I = 1ul; Args = {int, int, int, int, int}; typename std::enable_if<(I < sizeof (Tp ...)), void>::type = void]'
这只是一个示例(没有理由以这种方式声明变量...),但我想了解此错误的含义。
有人知道吗?
[EDIT2] 这是工作代码
#include <iostream>
#include <tuple>
#include <utility>
using namespace std;
template < size_t I = 0, typename... Args >
auto recursive_function( std::tuple< Args... > const& t )
-> typename std::enable_if< I == sizeof...(Args), void >::type
{
}
template < size_t I = 0, typename... Args >
auto recursive_function( std::tuple< Args...>const & t )
-> typename std::enable_if< I < sizeof...(Args), void >::type
{
cout << get<I>(t) << endl;
int i = 0;
recursive_function< I + 1, Args... >( t );
}
int main( int argc, char** argv )
{
try
{
auto t = make_tuple(1,2,3,4,5);
recursive_function( t );
}
catch( std::exception& e )
{
cerr << e.what() << endl;
}
return 0;
}
完整的错误信息在上面。 使用的编译器版本是 GCC 4.8.2,选项为 std=c++1y,我使用的是 Code::Blocks。奇怪的是,构建完成时有 2 个错误和 15 个警告,但实际输出考虑了更改(这样就没有考虑错误?)
您创建了一个变量但没有使用它。
您已启用所有警告 (-Wall
) 和错误警告。由于创建无意义的变量通常表示您犯了错误,因此编译器会发出警告。
所以一个警告(你创建了一个变量但没有使用它)产生了一个错误,然后它详细说明了这个错误是如何产生的(模板实例化将它的实例化包装为一个未使用的变量)。
在下一行插入 (void)i;
,警告消失。
请注意,warnings-as-errors 是一个很好的计划,坚持下去,同时也坚持 -Wall
(激活所有警告)。你的问题是你没有找到真正的错误是什么,你被编译器提供的模板扩展注释分散了注意力。