Reputation: 7546
What are the methods to achieve inline code in C++? I can only think about macros and inline functions. Are there more alternatives in C++11/17/20 (e.g. lambda) ? Advantages and disadvantages?
// do macros still make sense in modern C++ standards?
#define square(x) ((x)*(x))
// is this a good alternative to macros?
template <class T> inline T square(T x) { return x * x; }
EDIT: changed comment from "are macros still encouraged...?" to "do macros still make sense...?"
Upvotes: 1
Views: 157
Reputation: 20171
Macros have a big dis-advantage: They are namespace agnostic.
Imagine what happens if I extend your sample:
// are macros still encouraged in modern C++ standards?
#define square(x) ((x)*(x))
namespace My {
int square(int x) { return x * x; }
} // namespace My
So, IMHO, the answer is NO.
Remember that in C (where the preprocessor was introduced), there were no namespaces, and still have not been added until now.
Demo:
#define square(x) ((x)*(x))
namespace My {
int square(int x) { return x * x; }
} // namespace My
Preprocessed:
namespace My {
int ((int x)*(int x)) { return x * x; }
}
int main()
{
std::cout << My::((10)*(10));
}
in opposition to:
#include <iostream>
template <typename T>
T square(T x) { return x * x; }
namespace My {
int square(int x) { return x * x; }
} // namespace My
int main()
{
std::cout << My::square(10);
}
Output:
100
Upvotes: 3
Reputation: 4263
// is this a good alternative to macros?
template <class T> inline T square(T x) { return x * x; }
Yes, this is the preferred way. (Although templates in general don't require inline, whereas explicit template specializations and instantiations do, it is ok to be consistent and write what one means).
Also note that constexpr
functions and constructors are implicitly inline.
Also note that using final
(where appropriate) in the context of virtual overloading can help inline even some virtual methods (check this post for some examples and explanation).
Upvotes: 5
Reputation: 1247
Macros should be the last resort in C++.
They're not inherently bad, but they're not checked by the compiler.
Macro expansion is a little more than text replacement done before compiling, therefore you're writing code that will be checked only after the expansion.
That means that if you make a mistake find the error could be harder, also debugging will be harder, because you won't be able to jump into the macro code.
Also, you have to be careful with parentheses and with multiple evaluation.
Last but not least, all the other things pointed out by the other answers apply too.
Upvotes: 1
Reputation: 123450
Macros never were encouraged. Consider that the macro is not doing the same as the function eg here:
int foo() {
static int x = 0;
++x;
return x;
}
std::cout << square(foo());
And that is just one downside of the macro. If you want a function that takes a parameter and returns a value then that is not a macro.
Upvotes: 3
Reputation: 13759
It smells like "opinion-based", some people tend to dislike macros more than others.
Usual disadvantages of macros:
square
, even as a class methodTo mitigate the later one, name macros with ALL_CAPS, and don't name anything else like this.
The advantages of macros are:
Upvotes: 1