我遇到了一个奇怪的问题:
metadata.h:
class metadata
{
public:
metadata ( std::string filename );
template <class T> T get ( std::string key ) { return m_data.get<T> ( key ); }
private:
boost::property_tree::ptree m_data;
};
metadata.cpp:
metadata::metadata ( std::string filename )
{
try {
boost::property_tree::read_info ( filename, m_data );
} catch ( boost::property_tree::file_parser_error err ) {
std::cerr << "[!] Unable to open "
<< filename
<< ": "
<< err.message()
<< "!"
<< std::endl;
throw except ( "Error opening metadata file." );
}
}
asset.h:
template <class T> class assetManager {
public:
void load ( std::string filename );
T get ( std::string filename );
T operator[] ( std::string filename );
void drop ( std::string filename ) { m_assets.erase ( filename ); }
void clear() { m_assets.clear(); }
private:
std::map<std::string,T> m_assets;
};
template <class T> void assetManager<T>::load ( std::string filename )
{
if ( m_assets [ filename ] == nullptr ) {
m_assets.erase ( filename );
m_assets.insert ( std::pair <std::string,T> ( filename, new T ( filename ) ) );
}
}
template <class T> T assetManager<T>::get ( std::string filename )
{
T ret = m_assets.at ( filename );
return ret;
}
出于某种原因,这一行在这里:
m_metadata.load ( boost::filesystem::current_path().string() + "/engine.conf" );
我从g ++获得以下编译器错误:
src / core /../ core /../ asset / asset.h | 22 |错误:初始化时无法将'std :: string {aka std :: basic_string}'转换为'metadata *'
在任何情况下,据我所知,我编程的东西甚至有点类似于将字符串转换为我的元数据指针。有什么想法吗?
答案 0 :(得分:1)
在assetManager<T>::load
内部这个子表达式
std::pair <std::string,T> ( filename, new T ( filename ) )
显然是不正确的。 new T
将生成T *
。与此同时,您的对被宣布为T
作为其第二个成员。除非T *
中有正确的转化构造函数,否则您无法使用T
初始化T
。
如果T
为metadata
,那么针对此问题,我实际上会发出一条错误消息,指出无法将metadata *
转换为std::string
,而不是另一种方式。如果您尝试这个
metadata m(new metadata("test"));
另一个问题是您正在创建第一个成员具有类型std::string
的对。但是,在std::map<std::string, T>::value_type
中,该对中的第一个成员实际上是const std::string
。代码将进行编译,但需要从std::pair<std::string, T>
转换为地图std::pair<const std::string, T>
。这可能会成为性能问题。这就是为什么更好的想法是使用std::map<std::string, T>::value_type
作为对类型,而不是试图手动拼写出来。
在评论中,您声明m_metadata
为assetManager<metadata*>
。在这种情况下,T
为metadata *
。这解释了一切,包括错误消息。在这种情况下,问题更加简单和本地化。此
new T ( filename )
单独是导致错误的原因。这意味着new T
会生成metadata *
个对象,并尝试使用std::string
初始化它。因此错误消息。无法使用metadata *
初始化std::string
,因为无法将std::string
转换为metadata *
。
最重要的是,这样的new
表达式将返回metadata **
值,这绝对不是您需要的值。
答案 1 :(得分:0)
我将m_metadata更改为assetManager,然后进行了一些更改:
template <class T> class assetManager {
public:
void load ( std::string filename );
T get ( std::string filename );
T operator[] ( std::string filename );
void drop ( std::string filename ) { m_assets.erase ( filename ); }
void clear() { m_assets.clear(); }
private:
std::map<std::string,T*> m_assets;
};
template <class T> void assetManager<T>::load ( std::string filename )
{
if ( m_assets [ filename ] == nullptr ) {
m_assets.erase ( filename );
m_assets.insert ( std::pair <std::string,T*> ( filename, new T ( filename ) ) );
}
}
template <class T> T assetManager<T>::get ( std::string filename )
{
T ret = *m_assets.at ( filename );
return ret;
}
它现在编译并运行。虽然我的问题已得到解决但 对我来说仍然是一个谜,为什么编译器认为我正在尝试将std :: string转换为元数据*。