无法使用元编程在可变参数模板中声明变量

时间:2015-02-19 14:24:40

标签: c++ c++11 variadic-templates template-meta-programming

我正在使用可变参数模板函数为每个参数执行一个函数。迭代使用元编程,但是存在一个问题:我不能在其中声明一个简单的变量。这是一个例子:

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个警告,但实际输出考虑了更改(以便不考虑错误?)

1 个答案:

答案 0 :(得分:1)

您创建了一个变量并且没有使用它。

您已启用所有警告(-Wall)并启用了警告错误。由于创建一个无意义的变量通常是一个错误的标志,编译器会发出警告。

因此,警告(您创建了一个变量并且未使用它)会生成错误,然后它会提供有关此错误如何发生的详细信息(模板实例化将其实例化包装为未使用的变量)。

在下一行插入(void)i;,警告就会消失。

请注意,警告错误是一个很好的计划,保持开启,并继续-Wall(激活所有警告)。您的问题是您未能找到真正的错误,您在哪里分散了编译器提供的模板扩展注释。