The place you define a constexpr
function affects how you can use it. In particular:
C++14[expr.const]p2:
A conditional-expression e
is a core constant expression unless the evaluation of e
, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:
- …
- an invocation of an undefined
constexpr
function or an undefined constexpr
constructor;
So you can't use a constexpr
function in a constant expression (template argument, constexpr
variable initializer, global variable initializer that needs to be evaluated statically, array bound expression, maybe others) if it's only been declared but not defined yet.
Similarly, as dyp commented,
C++14[dcl.constexpr]p2
… constexpr
functions and constexpr
constructors are implicitly inline
(7.1.2).
That implies the answer to your first question: defining the constexpr
function in a header won't cause duplicate symbols. It also means that if you declare a constexpr function in a header, and then call it in a translation unit, even only at runtime, "An inline function shall be defined in every translation unit in which it is odr-used." from C++14[basic.def.odr]p4.
Note that the rules for constant expressions and calls in general are different: calls in general require the definition to be somewhere in the translation unit: constant expressions require the definition to be before the constant expression.