When defining a member function out-of-line, which qualifiers must appear in the declaration / definition / both?

瘦欲@ 提交于 2019-12-01 20:19:12
dasblinkenlight

General rule is that when removing a qualifier produces a different function overload, that qualifier must appear in both places. All other qualifiers stay in the declaration.

The three qualifiers that must appear in both places are const and the two kinds of reference qualifiers, which appear in the C++11 standard:

void foo() const;
void foo() &;
void foo() &&;

All other qualifiers stay in the declaration.

The best way to know which modifiers (or "specifiers") have to be used in which instance is to understand what each one of them means, and what they do.

const is a part of the method's "signature". A signature consists of what the function returns, the types of its parameters, and whether it is a constant method (the const part). That cannot be changed, and must remain as is.

Everything else, virtual, and override in your list, is related to the method's declaration. It's not a part of the method's signature, and can only appear in the method's declaration.

The only rule of thumb, if there is one, is that anything that's a part of the method's signature must be unchanged, when the method is not defined inline. And if it's not, it must be a part of the declaration, only (but, as with every rule of thumb, there's always an exception, the inline keyword).

Note that default parameter values are not considered to be a part of the method's signature. Default parameter values must be specified in the declaration only. But, if the method is defined inline, the default parameter values wind up as part of the method's definition!

I will take another approach: My rule of thumb: put them in both places and then do what the compiler says. It implements the standard rules and it will make you follow them.

The problem with any rule of thumb is that you can't be sure it's ok for a particular example, so why not check from the start by default.

If you seldom use C++, there is no point in learning some rules that you can't 100% rely on them anyway. If you (start to) use C++ often, then after several times the compiler tells you what to do, you will get the gist yourself.

Because this post is not in the same tone with the others, I will go the rogue way all the way and give you this extremely unused with a dark corner case example: constexpr in an explicit instantiation

template <class T>
constexpr auto foo(T)
{
}

template constexpr auto foo(int);
//       ^
// 6 : error: explicit instantiation shall not use 'constexpr' specifier

It's not what you asked about, but is goes to show that you can apply this strategy to a broader set of similar problems, where you would otherwise need other rules of thumbs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!