Answer
Function-like macros do blind text substitution with no type checking, no scope, and pitfalls like multiple argument evaluation and operator-precedence bugs. Modern C++ replaces them with inline functions, templates, and constexpr, which are type-safe, respect scope, and debuggable. Macros remain only for things the language can't do (conditional compilation, stringizing).
#define SQ(x) ((x)*(x))
SQ(i++) // i incremented twice! use a constexpr function insteadReal-world example A MAX macro double-evaluates its arguments causing a subtle bug; a template function fixes it.