See http://eel.is/c++draft/temp.over.link#7.sentence-1



Sent from my Samsung Galaxy smartphone.

-------- Original message --------
From: Tobias Loew via Std-Discussion <std-discussion@lists.isocpp.org>
Date: 8/4/19 05:39 (GMT-05:00)
To: std-discussion@lists.isocpp.org
Cc: tobi@die-loews.de
Subject: [std-discussion] CTADs and equivalent parameter list

Hi,

I think the wording of [temp.deduct.guide] (3) leaves room for interpretation. It says

"... Two deduction guide declarations in the same translation unit for the same class template shall not have equivalent parameter-declaration-clauses."

I couldn't find any definition of "equivalence" between parameter-declaration-clauses and especially none for parameter-declaration-clauses containing template-types.

So, for example, the following code may or may not be valid.

 

#include <type_traits>

 

template<typename T>

class A{

public:

    A(int){}

    A(double){}

};

template<typename T, typename = std::enable_if_t<std::is_integral_v<T>>>

A(T) -> A<int>;

template<typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>

A(T) -> A<double>;                    // <- equivalent parameter-declaration-clause as above

int main(){

    auto a = A{5};

    auto b = A{5.123};

}

 

Apparently, all major compiler's latest versions agree that the code above is valid, though MSVC 19.20 and earlier rejected it and accepted only the following *single CTAD* version:

template<typename T, typename = std::enable_if_t<std::is_integral_v<T> || std::is_floating_point_v<T>>>

A(T) -> A<typename std::conditional_t<std::is_integral_v<T>, int, double>>;

I think, the last sentence of [temp.deduct.guide] (3) should be more specific, e.g.:

"... Two deduction guide declarations in the same translation unit for the same class template shall not have equivalent parameter-declaration-clauses <new>for a given specialization</new>."

Tobias