"ScL Feature"/
SCL Feature 0.0.1
C++20 composable proxy wrapper with pluggable executor strategy
Loading...
Searching...
No Matches
has_qualified_method.h File Reference

Compile-time predicate macro for cv-ref qualifier detection. More...

Go to the source code of this file.

Macros

#define SCL_HAS_QUALIFIED_METHOD(method, Type, ...)
 Compile-time predicate: checks whether Type has a dedicated overload of method whose cv-ref qualifiers exactly match those of Type.

Detailed Description

Compile-time predicate macro for cv-ref qualifier detection.

Macro Definition Documentation

◆ SCL_HAS_QUALIFIED_METHOD

#define SCL_HAS_QUALIFIED_METHOD ( method,
Type,
... )

Compile-time predicate: checks whether Type has a dedicated overload of method whose cv-ref qualifiers exactly match those of Type.

In C++ a method qualified as const& is implicitly callable on a mutable lvalue, because a mutable reference converts to a const one. A simple requires expression therefore cannot distinguish "the class has a @c const& overload" from "the class has a mutable @c & overload that is also callable on @c const&".

This macro solves the problem by comparing return types of calls with different cv-ref qualifiers. If the return types differ, the class must have separate overloads; if they are the same, the call is assumed to go through implicit cv-widening and the predicate returns false.

Algorithm
For each value category (lvalue / rvalue) the macro:
  1. Checks callability for all 4 cv combinations (mutable, const, volatile, const volatile).
  2. For each pair where the "narrower" qualifier is callable through a "wider" one, compares decltype of the two calls. If both return the same type, the narrower call is considered implicit — the overload does not exist for that qualifier.
  3. For the rvalue const case an additional cross-category check is performed (see MSVC note below).
Implementation note — if constexpr guards
Return-type comparisons (::std::is_same_v) are placed inside if constexpr blocks that first verify callability, ensuring decltype is never evaluated on an ill-formed call expression. This avoids the Clang limitation where requires { requires EXPR; } inside a constexpr-evaluated lambda body is rejected.
Constraints — different return types required
Overloads of the same method name with different cv-ref qualifiers must have different return types. If two overloads return the same type, the macro cannot tell them apart and will produce a false negative (report no dedicated overload where one exists).
struct Good {
bool foo() &; // bool ≠ int → distinguishable
int foo() const &;
};
struct Bad {
int foo() &; // int == int → indistinguishable!
int foo() const &;
};
Constraints — volatile qualifiers
volatile overloads follow the same return-type discrimination rules. If the class has both volatile& and const volatile& overloads, their return types must also differ.
Constraints — non-ref-qualified methods
A method without any ref-qualifier (e.g. void foo() const) is callable on both lvalues and rvalues. The macro treats such methods as having dedicated overloads for both categories, provided the return-type discrimination passes.
MSVC note — const& callable on rvalues
MSVC (as a non-standard extension, enabled by default) allows const& ref-qualified member functions to be called on rvalues. This means can_rv_c will be true even when no const&& overload exists. To compensate, the macro performs a cross-category return-type comparison: it checks whether the return type of calling through const&& differs from calling through const&. If they match and no mutable/const rvalue return-type difference exists, the const&& call is deemed implicit and the predicate returns false.
Example
struct Target {
bool get() &;
int get() const &;
float get() &&;
};
// true — dedicated & overload exists (bool ≠ int)
static_assert( SCL_HAS_QUALIFIED_METHOD(get, Target &));
// true — dedicated const& overload exists
static_assert( SCL_HAS_QUALIFIED_METHOD(get, Target const &));
// true — dedicated && overload exists
static_assert( SCL_HAS_QUALIFIED_METHOD(get, Target &&));
// false — no const&& overload; const& is called implicitly
static_assert(!SCL_HAS_QUALIFIED_METHOD(get, Target const &&));
#define SCL_HAS_QUALIFIED_METHOD(method, Type,...)
Compile-time predicate: checks whether Type has a dedicated overload of method whose cv-ref qualifier...
Definition has_qualified_method.h:122
Parameters
methodUnqualified method name (may contain template keyword for explicit template arguments).
TypeA cv-ref qualified type, e.g. const MyClass &.
...Parameter types for the method call (may be empty).