开发者

c++ implementing friend/inline functions

I can't seem to find the answer to this newbie question. If I have a class // Header file (.h)

Class X {
public:
  friend bool operator==(const X&开发者_StackOverflow社区;, const X&);
  inline size_type rows() const;
};

etc... when I go to implement the .cpp file of X, should I include the words inline & friend in the function names in the .cpp file. ie, should I implement my file similar to the below

// CPP file (.cpp)
#include "X.h"
friend bool operator==(const X&, const X&) {
  //implementation goes here
  //return true/false
}

inline size_type rows() const {
  return r;
}

or should I not include these i.e. like below

#include "X.h"
bool operator==(const X&, const X&) { ... }

size_type rows() const { ... }


No, you shouldn't, i.e. the 2nd version is correct.

friend can only be used within a class definition (it has no meaning outside of it), and the compiler looks for the function signature to find the definition of the friend function declared within your class X.

inline is used in header files (although, I guess, technically it is possible to use it in a cpp file too, just it makes no sense there). And note that inline makes sense only if you actually define the function right there - it can have no effect if you provide the function definition separately, in a cpp file.

The point of inline is to hint the compiler that the function in question can be inlined (it is no guarantee, though - the compiler is free to decide whether it inlines that function or not). If the function is inlined, any calls to it are replaced by a copy of the function body. This is practically always done for performance benefits, to save the costs of function calls, at the expense of potentially increasing program size. Now, if we want to inline a function, we want it to be inlined all over the place, not only within a single compilation unit; this is why it makes little sense to use the inline keyword inside an implementation file.


When defining friend functions you can use one of two different options:

Define the friend function inside the class definition

namespace Test {
class test {
   int priv;
   friend void foo( test const & t ) { std::cout << t.priv << std::endl; }
};
}

Define them in the enclosing namespace:

namespace Test {
class test {
   int priv;
   friend void foo( test const & t );
};
void foo( test const & t ) {
   std::cout << t.priv << std::endl;
}
}

But note that there are differences regarding lookup. In particular, the first case is more restrictive (and thus should be preferred) as only ADL (Argument Dependent --aka Koening-- Lookup) will find it, while in the second case the function will be considered whenever that namespace is considered.

That is, for the compiler to consider the first function as an overload, the argument at the place of call must be a test, while in the second case it will be considered whenever the identifier matches, and might be considered as a valid option if the argument is convertible to test.


You don't want the friend prefix on the function body, just the signature in the header.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜