错误:“2次重载有类似的转换”

时间:2016-02-02 19:31:35

标签: c++ templates c++11 overloading

编辑: 当我写这个问题时,我注意到方法std::string GetNodeValue(const std::string& nodePath, const char * defaultValue)不是const。正如 LogicStuff 在他的评论中也提到的那样,添加const资格证明了歧义。

我知道这个问题已经被问及here以及其他几次。我理解潜在的问题,但我无法弄清楚为什么它会在这个特殊的情况下发生,它已经唤醒了我的好奇心。

我有以下课程:

class ConfigurationReader
{
public:
    // ...   
    std::string GetNodeValue(const std::string& nodePath, const char * defaultValue)
    {
        const std::string temp(defaultValue);
        return GetNodeValue(nodePath, temp); 
    }    

    template <typename T> T GetNodeValue(const std::string & nodePath, T defaultValue) const 
    {
        boost::optional<T> nodeValue = configuration.getNodeValueNothrow<T>(nodePath);
        if ( nodeValue ) 
        {
            return *nodeValue;
        }
        LogConfigurationProblemsCri(logger, "Node not found: " << nodePath << ", Default value: " << defaultValue);
        return defaultValue;
    }
    // ...    
};

模板方法还为int16_tuint16_t等类型提供了多种专精,依此类推,直至uint64_t

使用时它就像一个魅力:

string someValue = configurationReaderPtr->GetNodeValue("some_noe", "");
uint32_t otherValue = configurationReaderPtr->GetNodeValue("other_node", 11000);
bool yetAnother = configurationReaderPtr->GetNodeValue("other_node", true);

除一例外:

uint32_t otherValue = configurationReaderPtr->GetNodeValue("other_node", 0);

我一直得到的错误是: “2次重载有类似的转换 可能是' std :: string ConfigurationReader :: GetNodeValue(const std :: string&amp;,const char *)'或' uint32_t ConfigurationReader :: GetNodeValue(const std :: string&amp; ,uint32_t)const '“

我尝试投射“默认”值:uint32_t(0)static_cast<uint32_t>(0)0U但没有任何运气。

我应该指出,我已经找到了解决方法

uint32_t otherValue = 0;
otherValue = configurationReaderPtr->GetNodeValue("other_node", otherValue);

但这并不能解决我的好奇心。我目前正在使用Microsoft Visual Studio 2012 Express并增强1.54库。

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

这是因为0是空指针的文字(在现代C ++中用&#34; nullptr&#34;代替)。

因此0可以是int或空指针,尤其是char *

编辑以添加一些参考: 您可以在标准中找到它

  

4.10指针转换   空指针常量是值为零的整数文字(2.13.2)或类型为std :: nullptr_t的prvalue

(最后一个是对nullptr的引用)

答案 1 :(得分:1)

认为两种重载都同样可行
configurationReaderPtr->GetNodeValue("other_node", 0);

,因为:

  1. 需要从0进行隐式转换,其类型为intconst char *

  2. 需要从ConfigurationReader*ConfigurationReader const*的隐式转换(调用const - 合格的成员函数)

  3. 在进行两次重载(同等)const - 限定后,代码编译(首选函数模板)。第一次重载也不会首先修改任何成员。

    Live on Coliru

答案 2 :(得分:-1)

在您的特定示例中,将字符串版本的签名更改为

似乎是谨慎的
std::string GetNodeValue(const std::string& nodePath, const std::string defaultValue)

这将消除任何歧义。