命名空间中的函数重载(与具有静态成员的类相比)是个坏主意吗

Is function overloading in a namespace (compared to a class with static members) a bad idea?

本文关键字:静态成员 重载 函数 命名空间      更新时间:2023-10-16

这是一个关于一个想法的问题,而不是一个真正的代码

在过去,我总是写很多方法重载,这很好:

class myclass
{
public:
    std::string method(type1 a)
    {
        return method(...);
    }
    std::string method(type2 a)
    {
        return ....;
    }
}

这真是太棒了。

这个问题从昨天开始,当时我写了一个函数重载是一个命名空间:

namespac myspace
{
    std::string func(type1 a)
    {
        return func(...);
    }
    std::string func(type2 a)
    {
        return ....;
    }
}

这里的问题是,在名称空间内部,编译器不知道第二个函数。因此,它试图将给定的类型转换为与第一个函数匹配的类型。不幸的是,编译器没有告诉我这是我的错误。虽然我向函数发送了type2,但它试图将其转换为type1来调用自己,结果是stackoverflow。

尽管改变函数的顺序可以解决问题,但我想知道在专业C++编程中,在命名空间中使用函数重载是不是一个坏主意?

正如有人评论的那样,这个问题不是关于重载函数,而是关于函数声明的顺序。

当编译器看到时,命名空间中的错误很明显

std::string func(type1 a)
{
    return func(/*expect type2*/);
}

它必须知道当时func(/*expect type2*/)的原型/定义。

然而,在您的类定义中:

class myclass
{
public:
    std::string method(type1 a)
    {
        return method(/*expect type2*/); // OKAY, no problem here
    }
    std::string method(type2 a)
    {
        return ....;
    }
}

编译器不会抛出任何错误,尽管method(/*expect type2*/)的原型/定义在该位置未知。为什么?

据此http://www.tutorialspoint.com/cplusplus/cpp_inline_functions.htm

类定义中的函数定义是内联函数定义,即使不使用内联说明符也是如此。

这意味着,当编译器编译myClass时,它只编译成员原型,当然,在本例中没有错误。稍后将编译成员定义,例如当您调用该成员时。此时,myClass中所有成员函数的原型都是完全已知的。因此,编译器不会抛出任何错误。

EDIT:名称空间是名称空间,类是类;它们有不同的含义。选择名称空间或类取决于您自己的情况,而不是希望消除函数顺序错误。在您的示例中,您仍然可以通过声明所有需要的原型来使用名称空间:

namespac myspace
{
    std::string func(type2 a); // prototype
    std::string func(type1 a)
    {
        return func(...); // fine
    }
}

因此,最佳实践总是在定义/调用之前声明原型:(