This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4570. COMMON-DOMAIN should test for convertibility to default_domain

Section: 33.9.2 [exec.snd.expos] Status: New Submitter: Eric Niebler Opened: 2026-04-13 Last modified: 2026-04-17

Priority: Not Prioritized

View all other issues in [exec.snd.expos].

View all issues with New status.

Discussion:

P3826R5 accepted at the Croydon meeting adds the following paragraph to 33.9.2 [exec.snd.expos]:

For a pack of subexpressions domains, COMMON-DOMAIN(domains...) is expression-equivalent to common_type_t<decltype(auto(domains))...>() if that expression is well-formed, and indeterminate_domain<Ds...>() otherwise, where Ds is the pack of types consisting of decltype(auto(domains))... with duplicate types removed.

My intention with this paragraph was that two domains such as below would have a COMMON-DOMAIN of default_domain:

struct my_thread_pool_domain : std::execution::default_domain
{};

struct my_parallel_runtime_domain : std::execution::default_domain
{};

using domain-t = decltype(COMMON-DOMAIN(my_thread_pool_domain{}, my_parallel_runtime_domain{}));
static_assert(std::same_as<domain-t, default_domain>); // FAILS

But that's not how common_type_t works. Even though both domains derive from default_domain, they do not have a common type as determined by common_type_t.

We can patch this up easily enough: if common_type_t<Domains...> is ill-formed, we should check if common_type_t<default_domain, Domains...> is well-formed, this will correctly handle the case when all the domains are convertible to default_domain.

Proposed resolution:

This wording is relative to N5032 after application of the wording added by P3826R5.

  1. Modify 33.9.2 [exec.snd.expos] as indicated:

    -6- For a pack of subexpressions domains, COMMON-DOMAIN(domains...) is expression-equivalent to common_type_t<decltype(auto(domains))...>() if that expression is well-formed,; otherwise, common_type_t<default_domain(), decltype(auto(domains))...>() if that expression is well-formed; and indeterminate_domain<Ds...>() otherwise, where Ds is the pack of types consisting of decltype(auto(domains))... with duplicate types removed.