Thank you for your replies.

But the problem you are raising with your example already exists now:

template<typenamestruct no_default_alias3;

 

template<> struct no_default_alias3<int> {

   using type = std::vector<int>;

};

 

template<typename T> using alias3 = typename no_default_alias3<T>::type;

 

template<typename T> void bar(alias3<T>) { }

 

template<> struct no_default_alias3<double> {

   using type = std::vector<int>;

};

 

void foo()

{

   bar(std::vector<int>());

}


Sent from my iPhone

On 19 Nov 2021, at 15:50, Arthur O'Dwyer <arthur.j.odwyer@gmail.com> wrote:


Hi Nicolas,

Your idea breaks the fundamental reason alias templates were added to C++11: they are "transparent" to template type deduction.
Consider the following program using your proposed syntax:

template<typename> using no_default_alias2 = delete;
template<> using no_default_alias2<int> = std::vector<int>;

template<typename T> void bar(no_default_alias2<T>) { }

template<> using no_default_alias2<double> = std::vector<int>;

int main() {
    bar(std::vector<int>());
 }

Do you see the problem? The non-specializability of alias templates in C++ today is what avoids this problem.

HTH,
Arthur


On Fri, Nov 19, 2021 at 8:48 AM Nicolas Weidmann via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
Hello,

Currently most templates can be fully specialized, however, alias templates cannot.

 

As the following examples illustrate, the problem alias templates specialization would solve can currently be mimicked using alias traits.

 

But adding alias templates specialization would render to code more straightforward and readable:

 

The first example uses a default alias template followed by specializations.

The second example ‘deletes’ the default alias template, only allowing for specialized versions.

 

The first example achieved using traits:

 

///////////////////////////////////////////////////////////////

 

template<typename Tstruct AliasTrait {

   using type = std::set<T>;

};

 

template<> struct AliasTrait<int> {

   using type = std::vector<int>;

};

 

template<> struct AliasTrait<double> {

   using type = std::list<double>;

};

 

template<typename Tvoid foo()

{

   typename AliasTrait<T>::type values;

}

 

The first example achieved using alias template specialization:

 

///////////////////////////////////////////////////////////////

 

template<typenameusing alias = std::set<T>;

 

template<> using alias<int> = std::vector<int>;

template<> using alias<double> = std::list<double>;

 

template<typename Tvoid foo()

{

   alias<T> values;

}

 

The second example achieved using traits:

 

///////////////////////////////////////////////////////////////

 

template<typenamestructNoDefaultAliasTrait;

 

template<> struct NoDefaultAliasTrait<int> {

   using type = std::vector<int>;

};

 

template<> structNoDefaultAliasTrait<double> {

   using type = std::list<double>;

};

 

template<typename Tvoid bar()

{

   typename NoDefaultAliasTrait<T>::typevalues;

}

 

The second example achieved using alias template specialization and introducing ‘deletion’ of the generic alias template:

 

///////////////////////////////////////////////////////////////

 

template<typenameusing no_default_aliasdelete;

 

template<> using no_default_alias<int> = std::vector<int>;

template<> using no_default_alias<double> = std::list<double>;

 

template<typename Tvoid bar()

{

   no_default_alias<T> values;

}

 

Regards,

 

Nicolas





Sent from my iPhone
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals