简体   繁体   中英

Inline Function in Namespace Scope and Static Function in Class Scope

Is there any semantic difference between the two in the title?

For example, I can write,

class Hi{
public:
  static void Print(){
    printf("hi\n");
  }
};

but also,

namespace Hi{
  inline void Print(){
    printf("hi\n");
  }
}

I'm of course assuming both of these definitions are in the header. Is it just a matter of style?

A main difference is that namespaces can be extended, while classes can be inherited. This difference was important for "enum wrappers" in C++03. Some people strongly favored wrapping enums in classes, and others strongly favored wrapping them in namespaces, while perhaps most didn't care and didn't wrap.

Namespaces support argument dependent lookup, while classes don't (except for calls of friend functions defined in class definitions, and then it's really namespace ADL kicking in).

Classes support access control (public, protected, private) while namespaces don't. With namespaces the technique corresponding to private access is a nested namespace called detail or impl or some such. But this is just convention, not something the compiler can check and enforce.

I guess that since the above is what occurred to me first, it's probably the most relevant.

Worth noting: libraries that uses classes as a kind of faux namespace mechanism do exist (in particular I ran into an XML parser library of that kind), but they are very rare , and I doubt that any new libraries do this except for possible the above mentioned enum wrapping, which however was made less important by the scoped enums of C++11.

Although the class in your first example serves as a makeshift namespace, the differences are not limited to style.

For example, static member functions get access to private members of the class, such as other static functions of the same class, private types defined inside the class, and private static variables defined inside the class.

You can emulate a lot of this behavior with namespaces and static non-member functions / variables defined in the scope of a translation unit. However, the emulation would not be complete when non-static members of the class need to share access to private members with static member functions. In this case you would need to provide additional functionality to expose private members to non-members, while member functions would get it for free.

Here is an example based on your code:

class Hi{
private:
    // This static member variable is defined in a cpp file
    static int count;
public:
    Hi() { // Let's pretend concurrency does not exist
        count++;
    }
    static void Print(){
        printf("You said Hi %d times\n", count);
    }
};

If you wanted to emulate the above behavior with namespaces, you would need to declare your Hi::Print a friend of a class, or provide a public function to get the current value of count .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM