无法将std::string转换为初始化

Cannot convert std::string to in initialization

本文关键字:转换 初始化 string std      更新时间:2023-10-16

我有一个奇怪的问题:

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} '转换为'元数据* '

在任何时候,据我所知,我没有编写任何类似于将字符串转换为元数据指针的程序。什么好主意吗?

assetManager<T>::load这个子表达式中

std::pair <std::string,T> ( filename, new T ( filename ) )

显然是错误的。new T会生成T *。同时,您的pair以T作为其第二个成员声明。你不能使用T *来初始化T,除非你在T中有一个合适的转换构造函数。

如果Tmetadata,那么对于这个问题,我实际上希望出现一个错误消息,说不可能将metadata *转换为std::string,而不是相反。如果您尝试执行

,您将看到相同的错误。
metadata m(new metadata("test"));

另一个问题是,您正在创建一个pair,其中第一个成员的类型为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_metadataassetManager<metadata*>。在这种情况下,Tmetadata *。这解释了一切,包括错误消息。在这种情况下,问题就更加简单和局部化了。这个

new T ( filename )

是导致错误的原因。这意味着new T产生一个metadata *对象,并尝试用std::string初始化它。因此出现了错误消息。不能用std::string初始化metadata *,因为不能将std::string转换为metadata *

最重要的是,这样的new表达式将返回metadata **值,这绝对不是您需要的。

我将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::字符串元数据*转换。

相关文章: