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

C++ 初始化时无法将std::string转换为,c++,C++,我有一个奇怪的问题: 元数据.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; };

我有一个奇怪的问题:

元数据.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;
};
我从g++获得以下编译器错误:

src/core/。/core/。/asset/asset.h | 22 |错误:无法在初始化中将'std::string{aka std::basic_string}'转换为'metadata*'

据我所知,在任何时候,我都没有编程过任何东西,甚至有点像将字符串转换成metdata指针。有什么想法吗?

assetManager::load
这个子表达式中

std::pair <std::string,T> ( filename, new T ( filename ) )
另一个问题是,您正在创建一对,其中第一个成员的类型为
std::string
。但是,在
std::map::value_type
中,该对的第一个成员实际上是
const std::string
。代码将被编译,但需要从
std::pair
转换为map的
std::pair
。这可能会成为性能问题。这就是为什么更好的方法是使用
std::map::value\u type
作为pair类型,而不是尝试手动拼写


在评论中,您指出
m_metadata
assetManager
。在这种情况下,
T
元数据*
。这解释了一切,包括错误消息。在这种情况下,问题更加简单和局部化。这个

new T ( filename )
导致错误的原因是孤独。这意味着
newt
生成一个
metadata*
对象,并尝试使用
std::string
对其进行初始化。因此出现了错误消息。无法使用
std::string
初始化
metadata*
,因为无法将
std::string
转换为
metadata*


除此之外,这种
新的
表达式将返回一个
元数据**
值,这绝对不是您所需要的。

我将m_元数据更改为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;
}
模板类assetManager{
公众:
无效加载(std::字符串文件名);
T get(std::字符串文件名);
T运算符[](标准::字符串文件名);
void drop(std::string filename){m_assets.erase(filename);}
void clear(){m_assets.clear();}
私人:
标准::映射m_资产;
};
模板无效assetManager::load(std::string文件名)
{
if(m_资产[文件名]==nullptr){
m_assets.erase(文件名);
m_assets.insert(std::pair(文件名,新T(文件名));
}
}
模板T assetManager::get(std::string文件名)
{
T ret=*m_assets.at(文件名);
返回ret;
}

它现在编译并运行。虽然我的问题已经解决了,但为什么编译器认为我在尝试std::string到metadata*的转换,这对我来说仍然是个谜

m_元数据的类型是什么?如果它是
元数据
,为什么在它没有这样的成员时调用
加载
?m_metadata是一个AssetManager我不清楚为什么它会在std::string和metadata或metadata*之间进行任何转换。它们是std::pair的不同部分。@yarokasear:我描述的问题与std::pair的任何部分都无关。问题是代码需要
元数据
,而您给它
元数据*
。程序将尝试使用您在
元数据
类中提供的单个转换构造函数将
元数据*
转换为
元数据
。要使用该构造函数,它将尝试将
元数据*
转换为
std::string
,因为该构造函数中唯一的参数是
std::string
类型。什么版本的g++?我一直在使用4.8.1(如果可以的话),我注意到编译器错误消息的有用性比旧版本有了很大的提高。如果
m_metadata
实际上是
assetManager
,那么它就一点也不神秘了。请看我回答的第二部分。
std::pair <std::string,T> ( filename, new T ( filename ) )
metadata m(new metadata("test"));
new T ( filename )
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;
}