【问题标题】:Crash When Cerr'ing A Variable From A Tuple从元组中提取变量时崩溃
【发布时间】:2013-11-03 22:23:34
【问题描述】:

由于某种原因,当我尝试 std::cerr std::tuple 中的一个变量时,我的程序崩溃了。我的猜测是std::get<int>( std::tuple ) 正在返回 garbledy-gook。由于标准中的一些奇怪的措辞,传递给std::tuple 的值是否会完全改变(在传入或调用 std::get( std::tuple )时有什么原因吗? ,或错误的实现)?例如,从副本中,当您尝试阅读一个(即std::get)时会发生一些愚蠢的事情等?

编辑:这个问题是抽象的,不一定是关于下面的代码,而是提供关于 std::tuple 的信息,我(和其他阅读这篇文章的人)将来可能能够使用。

更新:也适用于 MinGW GCC 4.4.1。

更新:
我刚刚注意到我的代码在 ideone.com 上运行:

#include <iostream>
#include <string>
#include <vector>
#include <tuple>
#include <typeinfo>
#include <stdio.h>
#include <string.h>

template< int IETORATOR_T, typename TUPLE, typename FUNCTION_POINTER_T, typename... ARGUMENTS_T >
struct FunctionRunner
{
    FunctionRunner( TUPLE* tuple, FUNCTION_POINTER_T functionToRun, ARGUMENTS_T... arguments )
    {
        std::cerr << "Hi there!\n";
        //TEST CODE.//
        ///////////////////////////////////////////
        /////I can read from the value.//
        auto j = std::forward< decltype( std::get< IETORATOR_T >( *tuple ) ) >( std::get< IETORATOR_T >( *tuple ) );
        //I can write to the value.//
        j += 2;
        std::cerr << "------------\n";
        //I cant cerr the value? 0.0//
        std::cerr << "Passing " << j << "\n";
        FunctionRunner< IETORATOR_T - 1, TUPLE, FUNCTION_POINTER_T, decltype( std::get< IETORATOR_T >( *tuple ) ), ARGUMENTS_T... > runner{ 
                tuple, functionToRun, std::get< IETORATOR_T >( *tuple ), arguments... };
    }
};
template< typename TUPLE, typename FUNCTION_POINTER_T, typename... ARGUMENTS_T >
struct FunctionRunner< ( -1 ), TUPLE, FUNCTION_POINTER_T, ARGUMENTS_T... >
{
    FunctionRunner( TUPLE* tuple, FUNCTION_POINTER_T functionToRun, ARGUMENTS_T... arguments ) {
        functionToRun( arguments... );
    }
};

template< typename... ARGUMENT_TYPES_T >
struct ArgumentMaker
{
    std::tuple< ARGUMENT_TYPES_T... >* argumentData;
    ArgumentMaker( ARGUMENT_TYPES_T... arguments ) {
        argumentData = new std::tuple< ARGUMENT_TYPES_T... >( std::forward< ARGUMENT_TYPES_T >( arguments )... );
    }
    ~ArgumentMaker() {
        delete argumentData;
    }
    template< typename FUNCTION_POINTER_T >
    void ExecuteFunction( FUNCTION_POINTER_T functionToRun ) {
        FunctionRunner< ( std::tuple_size< std::tuple< ARGUMENT_TYPES_T... > >::value - 1 ), 
                std::tuple< ARGUMENT_TYPES_T... >, FUNCTION_POINTER_T > runner{ argumentData, functionToRun };
    }
};

void Test( int a, double d, float c ) {
    std::cerr << a << " " << d << " " << c << "\n";
}

int main()
{
    int a = 2;
    double b = 34.5;
    float c = 45.6f;
    auto* maker = new ArgumentMaker< int, double, float >( a, b, c );
    maker->ExecuteFunction( &Test );
    delete maker;
    return ( 0 );
}

我在桌面上使用的编译器是 MinGW 的 GCC 4.8.1-4。这是编译器错误吗?

【问题讨论】:

  • 展示一些代码怎么样,最好是SSCCE的形式?
  • @DanielFrey 我确实发布了代码。它有点长(对于这个特定的例子来说,它有点难),而且这个问题是抽象的,我现在不是在寻求解决我的问题的帮助,而是我可以参考的信息未来。
  • 为什么该代码使用newdelete?没有什么需要动态分配
  • @JonathanWakely 我只是想消除任何出于测试目的而复制任何内容的可能性。
  • 您应该出于测试目的简化代码,而不是使其复杂化。您使用forward 的目的是什么? tuple_element 会比 decltype 更简单,但我会完全摆脱 forward。最后,我很肯定问题是你的代码,而不是编译器错误。

标签: c++ c++11 stdtuple


【解决方案1】:

传递给std::tuple 的值是否会发生变化?

不,当然不是,除非你改变它们。 std::tuple 只是一个将值作为成员保存的结构,它没有任何神奇的属性会导致值静默更新。

您应该将代码简化为真正基本的东西,而不是那些无关紧要的混乱,看看是否可行:

#include <tuple>
#include <iostream>

int main()
{
    std::tuple<int> t{ 1 };
    std::cerr << std::get<0>(t);
}

如果这不起作用,让它变得更简单:

#include <iostream>

int main()
{
    int t = 1 ;
    std::cerr << t;
}

如果这不起作用,则您的 MinGW 安装中的某些内容非常损坏,但这与 tuple 或可变参数模板或动态分配或原始代码中的任何其他内容无关。

【讨论】:

    猜你喜欢
    • 2019-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 2011-08-02
    相关资源
    最近更新 更多