我有一个奇怪的问题:
元数据.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;
};
元数据.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." );
}
}
Assets .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}”转换为“元数据*”
据我所知,我从来没有在此处编写任何类似于将字符串转换为元数据指针的程序。有什么想法吗?
最佳答案
内部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>
进行转换到 map 的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 **
值(value),这绝对不是你需要的。
关于c++ - 无法将 std::string 转换为初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25335903/