了解方法重载规则

时间:2013-12-25 09:03:23

标签: c++ overloading overload-resolution

我有一个字符串类:

#include <stdint.h>

class CString {
public:
    CString() {}
    explicit CString(uint64_t ui64, int width = -1, int base = 10, char fillChar = ' ') {}
    CString(const char * str) {}

    CString arg(const CString& argument) const {return CString();}

    template <typename T>
    inline CString arg(T argument, int width = -1, int base = 10, char fillChar = ' ') const
    {
        return arg(CString(argument, width, base, fillChar));
    }
};

现在,我正在使用这个类:

void main()
{
    CString str;
    str.arg("123");
}

得到错误:

error C2665: 'CString::CString' : none of the 4 overloads could convert all the argument types
1>          source.cpp(6): could be 'CString::CString(uint64_t,int,int,char)'
1>          while trying to match the argument list '(const char *, int, int, char)'
1>          source.cpp(22) : see reference to function template instantiation 'CString CString::arg<const char*>(T,int,int,char) const' being compiled
1>          with
1>          [
1>              T=const char *
1>          ]

为什么不使用arg(CString&)构造函数调用CString(const char *)

2 个答案:

答案 0 :(得分:3)

注意:这会回答原始问题,然后再将其更改为其他问题。

  

为什么模板arg不能超载?

因为它至少需要两个参数,而你传递一个参数。

template <typename T>
inline CString arg(T argument, int width, int base = 10, char fillChar = ' ')
{ ... }

答案 1 :(得分:1)

致电时

str.arg("123");

最佳匹配是通过功能模板arg获得的,因为CString arg(const CString& argument)需要转换为用户定义的类型。然后函数模板调用

return arg(CString(argument, width, base, fillChar));

但是没有CString构造函数匹配您在这里传递的参数列表const char*, int, int, char

无法拨打CString(uint64_t, int, int, char),因为从const char*uint64_t的转换是无效转换。这个简化的代码示例表现出同样的问题:

#include <cstdint>
void foo(std::uint64_t) {}

int main()
{
  foo("hello");
}
  

错误:从'const char *'无效转换为'uint64_t {aka long long unsigned int}'[-fpermissive]

     

FOO( “你好”);

如果您要注释掉成员函数模板arg,则会通过从CString arg(const CString& argument)const char*的隐式转换来调用CString