C1001符合时间错误(无优化)

时间:2019-05-20 22:41:54

标签: c++ visual-c++ tuples variadic-templates

我正在一个项目中,我需要保存具有不同类型值的参数包(元组)(由于可能太多,因此无法重载函数)。我已经到达以下代码,但收到错误:

Error C1001 An internal error has occurred in the compiler.
tupletest.cpp 47

我已删除优化并禁用了整个程序的优化(以及删除了漫游和本地的Visual Studio文件夹以删除规范)

很抱歉阅读时间长(包括很多代码)

还尝试了以下形式:

template<class arg>
    std::tuple<arg> GetTuple()
{...}
template<class arg, typename... args>
    std::tuple<arg,args...> GetTuple(json::object::iterator it, json::object::iterator end)
{...}

但是我收到这样的错误:

Error C2440 'return': cannot convert from 'std::tuple<std::string,int,int,std::string,std::string>' to 'std::tuple<int,int,int,std::string,std::string>'
template<typename... args, class...refargs>
std::tuple<int, args...> GetTupleFromArgs(std::reference_wrapper<int> refarg, refargs... refargs)
{
    return std::tuple_cat(std::make_tuple(refarg.get()), GetTupleFromArgs<args...>(refargs...));
}
std::tuple<int> GetTupleFromArgs(std::reference_wrapper<int> refarg)
{
    return std::make_tuple(refarg.get());
}
template<typename... args, class...refargs>
std::tuple<float, args...> GetTupleFromArgs(std::reference_wrapper<float> refarg, refargs... refargs)
{
    return std::tuple_cat(std::make_tuple(refarg.get()), GetTupleFromArgs<args...>(refargs...));
}
std::tuple<float> GetTupleFromArgs(std::reference_wrapper<float> refarg)
{
    return std::make_tuple(refarg.get());
}
template<typename... args, class...refargs>
std::tuple<std::string, args...> GetTupleFromArgs(std::reference_wrapper<std::string> refarg, refargs... refargs)
{
    return std::tuple_cat(std::make_tuple(refarg.get()), GetTupleFromArgs<args...>(refargs...));
}
std::tuple<std::string> GetTupleFromArgs(std::reference_wrapper<std::string> refarg)
{
    return std::make_tuple(refarg.get());
}

int main()
{
    int a = -1;
    int b = 2;
    int c = 3;
    std::string r = "hel";
    std::string v = "he2l";

    std::tuple<int, int, int, std::string, std::string> tuple = GetTupleFromArgs(std::ref(a), std::ref(b), std::ref(c), std::ref(r), std::ref(v));
    //std::cout << _pack.GetInt<0>();

    std::cout << "Hello World!\n"; 
}

我希望元组中的值是-1,2,3,"hel","he2l",但是会收到编译时间Error C1001 An internal error has occurred in the compiler.

1 个答案:

答案 0 :(得分:0)

这是编译器错误。

因此,编译器内部发生了意外情况,这并不是(完全)您的错。

无论如何,我看到您混合使用类型名称和值名称。例如,在此功能中

// ................................VVVVVVV
template<typename... args, class...refargs>
std::tuple<int, args...> GetTupleFromArgs(std::reference_wrapper<int> refarg, refargs... refargs)
{ ............................................................................^^^^^^^....^^^^^^^

您将refargs命名为第二个可变参数列表的类型名称和相应值的名称。

错误的选择。

也许是激活编译器错误的选择。

GetTupleFromArgs()的所有三个递归版本都存在相同的问题。

GetTupleFromArgs的递归版本的另一个问题是,不能推论出第一个可变参数类型列表,因为它是相对于返回值的。

也许只是一些话题,但我建议您按照以下方式简单地重写GetTupleFromArgs()

template <typename ... As>
std::tuple<As...> GetTupleFromArgs (std::reference_wrapper<As> ... rAs)
 { return { rAs.get() ... }; }

这样,可以从函数的参数推导单个可变参数列表,而无需递归和重载

另一个建议:避免将tuple命名为std::tuple类型的变量。只是为了避免名称冲突。

以下是您的代码的简化(可编译)版本

#include <tuple>
#include <iostream>
#include <functional>
#include <type_traits>

template <typename ... As>
std::tuple<As...> GetTupleFromArgs (std::reference_wrapper<As> ... rAs)
 { return { rAs.get() ... }; }

int main ()
 {
   int a = -1;
   int b = 2;
   int c = 3;
   std::string r = "hel";
   std::string v = "he2l";

   auto tpe = GetTupleFromArgs(std::ref(a), std::ref(b), std::ref(c),
                               std::ref(r), std::ref(v));

   static_assert( std::is_same<decltype(tpe),
                     std::tuple<int, int, int, std::string, std::string>
                     >::value, "!" );
 }