Im trying to build a dictionary of properties that are read in from an XML blender scene and am running into an issue with templates and getting their type_info. The containing map is setup as the name of the property and its value which is stored into a struct of typeinfo and union. Is it possible to do it this way or does it have to recognize it on the specific type? I have made attempts to initialize the struct before passing it to the map, and even to copy the binary data to the union, but it errors everytime on getting typeid(T). And I have also attempted using tuples in the map instead of the struct. here's the line causing the error
line 80 = mProperties[name] = std::make_tuple(typeid(T), d);
The error
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
Code:
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);
}
};
The copy constructor of std::type_info
is deleted so you can't copy those objects into your map. However, typeid()
...
... refers to an object with static storage duration, of the polymorphic type
const std::type_info
or of some type derived from it.
... so you can store const std::type_info
pointers in your map:
#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";
}
Possible output:
bar: i
123
baz: d
3.14159
foo: NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
hello