C++ typeid 模板值到 union 的转换不可接受
C++ typeid template value into union no acceptable conversion
我正在尝试构建从 XML blender 场景中读取的属性字典,并且 运行 遇到模板问题并获取它们 type_info。包含映射设置为 属性 的名称及其存储在 typeinfo 和 union 结构中的值。是否可以这样做,还是必须在特定类型上识别它?我尝试在将结构传递给映射之前对其进行初始化,甚至将二进制数据复制到联合体,但每次获取 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 Studio19\Community\VC\Tools\MSVC.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 Studio19\Community\VC\Tools\MSVC.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 Studio19\Community\VC\Tools\MSVC.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 Studio19\Community\VC\Tools\MSVC.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 Studio19\Community\VC\Tools\MSVC.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);
}
};
std::type_info
的复制构造函数已删除,因此您无法将这些对象复制到您的地图中。但是,typeid()
...
... refers to an object with static storage duration, of the polymorphic type const std::type_info
or of some type derived from it.
... 这样您就可以在地图中存储 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
我正在尝试构建从 XML blender 场景中读取的属性字典,并且 运行 遇到模板问题并获取它们 type_info。包含映射设置为 属性 的名称及其存储在 typeinfo 和 union 结构中的值。是否可以这样做,还是必须在特定类型上识别它?我尝试在将结构传递给映射之前对其进行初始化,甚至将二进制数据复制到联合体,但每次获取 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 Studio19\Community\VC\Tools\MSVC.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 Studio19\Community\VC\Tools\MSVC.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 Studio19\Community\VC\Tools\MSVC.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 Studio19\Community\VC\Tools\MSVC.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 Studio19\Community\VC\Tools\MSVC.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);
}
};
std::type_info
的复制构造函数已删除,因此您无法将这些对象复制到您的地图中。但是,typeid()
...
... refers to an object with static storage duration, of the polymorphic type
const std::type_info
or of some type derived from it.
... 这样您就可以在地图中存储 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