Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I specialize std::common_type<A,B> so that it's naturally commutative?

std::common_type<T1, ..., TN> is a helper template in C++ which can find the common type which all of T1 ... TN are implicitly convertible to.

According the C++ spec, a user may specialize std::common_type<T1,T2> if certain conditions apply, and:

std::common_type<T1, T2>::type and std::common_type<T2, T1>::type must denote the same type.

However, common_type<T1, T2> might be a very complicated specialization for user types T1 and T2:

namespace std {

    template <typename T1, complicated_constraint_of<T1> T2, ...>
    struct common_type<complicated_expression_of<T1, ...>, complicated_expression_of<T2, ...>> {
        using type = complicated_type_expression_of<T1,T2>;
    };

}

In general, the constraint expressions are not necessarily symmetrical (for example, we might specify that T2 is a base of T1). This means that to preserve symmetry, we'd need to rewrite the entire specialization with T1 and T2 reversed, but doing that without making any mistake is extremely difficult and fragile.

How can I robustly define a commutative specialization of common_type<T1,T2> for my own types?

like image 506
trbabb Avatar asked Nov 16 '21 06:11

trbabb


People also ask

What are the different types of STD’s?

Herpes is another viral STD and it comes in two forms, HSV1 and HSV2. HSV1 is most often associated with cold sores, and HSV2 is most often associated with genital sores. However, it is possible to transmit herpes from the mouth to the genitals and vice versa.

What is the most common STD that is curable?

Chlamydia. Chlamydia is the most common curable STD. It infects the cervix in women and the penile urethra in men. Its most frequent symptoms are pain during sex and discharge from the penis or vagina. However, the reason chlamydia is one of the most common STDs is that most people who get chlamydia don't have symptoms for weeks, months,...

What are some STIs that are transmitted during sex?

Others aren't transmitted during sex but occur as a result of it. Here are some common STIs and diseases associated with sex, along with their symptoms . Chlamydia is the most common curable bacterial STI. 1 It infects the cervix, which is the opening to the uterus or womb.

What is a common type in C++?

For arithmetic types not subject to promotion, the common type may be viewed as the type of the (possibly mixed-mode) arithmetic expression such as T0() + T1() + ... + Tn() . The following behavior-changing defect reports were applied retroactively to previously published C++ standards.


1 Answers

Here is the C++20 solution I came up with:

// define concept of `common_type<A,B>` existing
template <typename A, typename B>
concept has_in_common_ordered = requires { common_type<A,B>::type; };

namespace std {
    
    // define common_type<A,B> if common_type<B,A>::type exists:
    template <typename A, has_in_common_ordered<A> B>
    struct common_type<A,B> : public common_type<B,A> {};
    
}

Now, with the above, the following should compile:

struct X {};
struct Y {};

namespace std {
    
    template<>
    struct common_type<X,Y> {
        using type = X; // or whatever
    };
    
}

int main() {
    // even though we only specialized for one ordering,
    // both orderings now exist:
    std::common_type<X,Y>::type a;
    std::common_type<Y,X>::type b;
}

I think one of two things is possible:

  1. This is a natural technique that should really just be part of the standard definition of std::common_type.
  2. This is extremely evil and you should never do it, for subtle reasons.

I await someone to tell me which one it is in the comments. ;)

like image 119
trbabb Avatar answered Oct 25 '22 04:10

trbabb