C1001 Ошибка во время компиляции (без оптимизаций) - PullRequest
0 голосов
/ 21 мая 2019

Я работаю над проектом, в котором мне требуется сохранить пакеты аргументов (кортежи) с различными типами значений (не может перегрузить функции, поскольку их слишком много).Я получил код ниже, но получаю сообщение об ошибке:

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 голосов
/ 21 мая 2019

Это ошибка компилятора.

Итак, внутри компилятора произошло нечто неожиданное, и это (не полностью) ваша ошибка.

В любом случае, я вижу, что вы смешиваете имена типов и имена значений; например, в этой функции

// ................................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, "!" );
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...