Motivation
All deferred objects currently use function-call syntax for evaluation:
That is natural for composed deferred expressions, but less conventional for value wrappers such as constant_ and variable_. Standard C++ wrapper types usually expose named accessors such as value() or get().
Proposed API
Add named accessors while retaining operator() for uniform deferred evaluation:
constant.get(); // const T&
std::move(constant).get(); // T
variable.get(); // T&
std::as_const(variable).get(); // const T&
std::move(variable).get(); // T
value() is another possible name. get() aligns with std::reference_wrapper; value() aligns with std::optional and communicates value access more explicitly.
Design considerations
- Mirror the existing cv/ref-qualified return types exactly.
- Preserve
noexcept and constexpr.
- Avoid duplicating implementation: either the named accessor or
operator() should delegate to the other.
- Retain
operator() so generic deferred evaluation and existing code remain unchanged.
- Decide whether mutating access through non-const
variable_::get() is intentional and document it.
- Consider whether named access belongs only on
constant_/variable_ or on every deferred expression. Restricting it to wrappers keeps the semantic distinction clear.
Compatibility
This can be a purely additive API change.
Acceptance criteria
Motivation
All deferred objects currently use function-call syntax for evaluation:
auto value = object();That is natural for composed deferred expressions, but less conventional for value wrappers such as
constant_andvariable_. Standard C++ wrapper types usually expose named accessors such asvalue()orget().Proposed API
Add named accessors while retaining
operator()for uniform deferred evaluation:value()is another possible name.get()aligns withstd::reference_wrapper;value()aligns withstd::optionaland communicates value access more explicitly.Design considerations
noexceptandconstexpr.operator()should delegate to the other.operator()so generic deferred evaluation and existing code remain unchanged.variable_::get()is intentional and document it.constant_/variable_or on every deferred expression. Restricting it to wrappers keeps the semantic distinction clear.Compatibility
This can be a purely additive API change.
Acceptance criteria
constant_exposes a named accessor for const lvalues and rvalues.variable_exposes named accessors for mutable lvalues, const lvalues, and rvalues.operator()overloads.constexprandnoexceptwhere the current operators are.operator()behavior remains supported.variable_, and move access.