Вопросы

Член функции-аксессора для вариативной шаблонной структуры

В качестве упражнения я разрабатываю ориентированный на цель планировщик действий в Unreal Engine 4. Я пытаюсь настроить свои собственные структуры, которые я могу использовать для динамического описания состояния мира, используя список данных переменной длины, состоящий из отдельных типов переменных. Я думал, что вариативные шаблонные структуры могут быть интересным способом сделать это, но при реализации метода доступа к значению я столкнулся с проблемами.

Я хочу, чтобы он работал, чтобы я мог создавать экземпляры этих структур во время выполнения, используя FDataKeys<T> в общих параметрах для FFact<T...>. Затем я хочу иметь функцию GetValue<S>(string Key), которая будет рекурсивно проверять ключи данных, пока не будет найдено совпадение. Я буду реализовывать параметр флага, чтобы указать на успех или неудачу поиска, но я получаю ошибку компиляции в моем рабочем коде, которая не имеет для меня смысла.

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

Сообщение об ошибке:

38:42: предупреждение: ISO C ++ запрещает использование ‘auto’ в объявлении параметра [-Wpedantic] При создании экземпляра ‘S FFact ‹T, R …› :: GetValue (const string &) [with S = char; Т = std :: basic_string; R = {}; std :: string = std :: basic_string] ‘:

50:45: требуется рекурсивно из ‘S FFact ‹T, R …› :: GetValue (const string &) [with S = char; Т = логический; R = {std :: basic_string ‹char, std :: char_traits, std :: allocator›}; std :: string = std :: basic_string] ‘

50:45: требуется от ‘S FFact ‹T, R …› :: GetValue (const string &) [with S = char; T = char; R = {bool, std :: basic_string ‹char, std :: char_traits, std :: allocator›}; std :: string = std :: basic_string] ‘

67:37: требуется отсюда

46:25: ошибка: невозможно преобразовать ‘std :: basic_string’ в ‘char’ в возвращении В функции-члене ‘S FFact ‹T, R …› :: GetValue (const string &) [with S = char; Т = std :: basic_string; R = {}; std :: string = std :: basic_string] ‘:

52: 5: предупреждение: элемент управления достигает конца непустой функции [-Wreturn-type]

Код:

// FFact struct experiments
#include <iostream>
#include <string>
#include <vector>
using namespace std;

// Key-Value data struct
template<typename T>
struct FDataKey
{
    FDataKey(string KeyStr, T Data)
    {
        Key = KeyStr;
        Value = Data;
    }
    
    string Key;
    T Value;
};

// Basic struct to enable generic recursion
template<typename ... T>
struct FFact
{
    // GetValue's bottom of the barrel
    // ToDo: Implement check that Key was not found
    template<typename S>
    S GetValue(string Key)
    {
        S defaultValue;
        return defaultValue;
    }
};

// Variadic templated container meant for FDataKey<> types only
template<typename T, typename ... R>
struct FFact<T, R...>
{
    // Constructors
    FFact(){}
    FFact(const FDataKey<T>& FirstValue, const auto& ...Rest) : Data(FirstValue), Remainder(Rest...)
    {}
    
    // Recursively check Data members for FDataKeys with matching keys
    template<typename S>
    S GetValue(const string& Key)
    {
        if(Data.Key == Key)
        {
            return Data.Value;
        }
        else
        {
            return Remainder.GetValue<S>(Key);
        }
    }
    
    // Member variables
    FDataKey<T> Data;
    FFact<R...> Remainder; 
};

// Run tests
int main() 
{
  // Setup testing Fact
  FFact<char, bool, string> f = FFact<char,bool,string>(
      FDataKey<char>("Initial", 'w'),
      FDataKey<bool>("Cake",false),
      FDataKey<string>("Marco","Polo")
  );
  
  cout << f.GetValue<char>("Initial") << endl;
  cout << f.GetValue<bool>("Cake") << endl;
  cout << f.GetValue<string>("Marco") << endl;
}

return Data.Value; — вы делаете return Data.Value; из каждого рекурсивного вызова, даже когда вы возвращаете S. Бывший. в GetValue<char>. C ++ статически типизирован, тогда каждый Data.Value должен быть преобразован в char.   —  person LazarusOfSuburbia    schedule 21.02.2021

Читать:
Как определить неудачные приведения с помощью оператора dynamic_cast?

Думаю, вот что меня смущает. Поскольку Data.Value не следует возвращать до тех пор, пока ключ не совпадет. Таким образом, единственным преобразованием типа должно быть преобразование S в typeof(Data.Value), которое должно выдавать ошибку только тогда, когда в вызове передаются неправильные универсальные типы.   —  person LazarusOfSuburbia    schedule 21.02.2021

should not be returned он не будет возвращен, но статически все пути должны быть действительными. Как int func() { if (0) { return std::string{}; } return 5; } не будет компилироваться, независимо от того, что строка никогда не возвращается.   —  person LazarusOfSuburbia    schedule 21.02.2021

Похожие записи

Запрос Firebase ничего не возвращает

admin

Swift — виджет не может получить доступ к группе приложений

admin

Ошибка pyinstaller при создании игры pygamezero

admin

Java 8 LocalDateTime

admin

Получить информацию из подгруппы firestore + FLUTTER

admin

Облачное хранилище — Получите фактическую дату создания файла

admin