Значение шаблона типа C ++ в объединении нет приемлемого преобразования - PullRequest
0 голосов
/ 19 февраля 2020

Я пытаюсь создать словарь свойств, которые считываются из сцены XML блендера, и столкнулся с проблемой с шаблонами и получением их type_info. Содержащая карта настраивается как имя свойства и его значение, которое хранится в структуре typeinfo и union. Возможно ли это сделать таким образом или он должен распознавать его по указанному типу c? Я предпринял попытки инициализировать структуру перед передачей ее на карту и даже скопировать двоичные данные в объединение, но каждый раз при получении typeid (T) возникают ошибки. И я также попытался использовать кортежи на карте вместо структуры. Вот строка, вызывающая ошибку

line 80 = mProperties[name] = std::make_tuple(typeid(T), d);

Ошибка

Severity    Code    Description Project File    Line    Suppression State
Error   C2679   binary '=': no operator found which takes a right-hand operand of type 'std::tuple<type_info,std::basic_string<char,std::char_traits<char>,std::allocator<char>>>' (or there is no acceptable conversion)   OgreEngine  D:\SchoolAndProjects\Programs\ETGG 3802_01 Realtime Interactive Prog 2\Lab 1\OgreEngine\OgreEngine\include\component.h  80  
Error   C2679   binary '=': no operator found which takes a right-hand operand of type 'std::tuple<type_info,int>' (or there is no acceptable conversion)   OgreEngine  D:\SchoolAndProjects\Programs\ETGG 3802_01 Realtime Interactive Prog 2\Lab 1\OgreEngine\OgreEngine\include\component.h  80  
Error   C2679   binary '=': no operator found which takes a right-hand operand of type 'std::tuple<type_info,float>' (or there is no acceptable conversion) OgreEngine  D:\SchoolAndProjects\Programs\ETGG 3802_01 Realtime Interactive Prog 2\Lab 1\OgreEngine\OgreEngine\include\component.h  80  
Error   C2679   binary '=': no operator found which takes a right-hand operand of type 'std::tuple<type_info,double>' (or there is no acceptable conversion)    OgreEngine  D:\SchoolAndProjects\Programs\ETGG 3802_01 Realtime Interactive Prog 2\Lab 1\OgreEngine\OgreEngine\include\component.h  80  
Error   C2679   binary '=': no operator found which takes a right-hand operand of type 'std::tuple<type_info,bool>' (or there is no acceptable conversion)  OgreEngine  D:\SchoolAndProjects\Programs\ETGG 3802_01 Realtime Interactive Prog 2\Lab 1\OgreEngine\OgreEngine\include\component.h  80  
Error   C2280   'void *std::pair<const std::string,std::tuple<type_info,OgreEngine::Component::data>>::__delDtor(unsigned int)': attempting to reference a deleted function OgreEngine  C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.24.28314\include\xmemory 676 
Error   C2280   'void *std::pair<const std::string,std::tuple<type_info,OgreEngine::Component::data>>::__delDtor(unsigned int)': attempting to reference a deleted function OgreEngine  C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.24.28314\include\xmemory 676 
Error   C2280   'void *std::pair<const std::string,std::tuple<type_info,OgreEngine::Component::data>>::__delDtor(unsigned int)': attempting to reference a deleted function OgreEngine  C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.24.28314\include\xmemory 676 
Error   C2280   'void *std::pair<const std::string,std::tuple<type_info,OgreEngine::Component::data>>::__delDtor(unsigned int)': attempting to reference a deleted function OgreEngine  C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.24.28314\include\xmemory 676 
Error   C2280   'void *std::pair<const std::string,std::tuple<type_info,OgreEngine::Component::data>>::__delDtor(unsigned int)': attempting to reference a deleted function OgreEngine  C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.24.28314\include\xmemory 676 

Код:

private:
    union data
    {
        std::string sVal;
        bool bVal;
        int iVal;
        float fVal;
        double dVal;
    };
    struct propertyData {
        type_info dataType;
        data val;
    };

protected:
    GameObject* Parent;
    std::map<std::string, std::tuple<type_info, data>> mProperties;

public:
    /// Append the property of type T to the property map container
    template<typename T>
    void add_xml_property(std::string name, T d)
    {
        if (mProperties.find(name) == mProperties.end())
        {

            //struct propertyData pData = {typeid(T), d};
            //memcpy_s((void*)&pData.val, sizeof(d), (void*)&d, sizeof(d));
            mProperties[name] = std::make_tuple(typeid(T), d);
        }
    };

1 Ответ

0 голосов
/ 19 февраля 2020

Конструктор копирования std::type_info удален, поэтому вы не можете скопировать эти объекты на карту. Однако typeid() ...

... относится к объекту с stati c сроком хранения , типа polymorphi c const std::type_info или некоторого типа, полученного из него.

... так что вы можете хранить const std::type_info указатели на вашей карте:

#include <iostream>
#include <map>
#include <string>
#include <typeinfo>
#include <utility>
#include <variant>

using data = std::variant<std::string, bool, int, float, double>;

std::ostream& operator<<(std::ostream& os, const data& v) {
    switch(v.index()) {
    case 0: os << std::get<0>(v); break;
    case 1: os << std::get<1>(v); break;
    case 2: os << std::get<2>(v); break;
    case 3: os << std::get<3>(v); break;
    case 4: os << std::get<4>(v); break;
    }
    return os;
}

std::map<std::string, std::pair<const std::type_info*, data>> mProps;

template<typename T>
void add_xml_property(const std::string& name, T d) {
    if(mProps.find(name) == mProps.end()) mProps[name] = {&typeid(T), d};
}

int main() {
    add_xml_property("foo", std::string("hello"));
    add_xml_property("bar", 123);
    add_xml_property("baz", 3.14159);

    for(auto& [k, v] : mProps)
        std::cout << k << ": " << v.first->name() << '\n' << v.second << "\n\n";
}

Возможный вывод:

bar: i
123

baz: d
3.14159

foo: NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
hello
...