template<typename> struct 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>());
}
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,ArthurOn 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 T> struct 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 T> void foo()
{
typename AliasTrait<T>::type values;
}
The first example achieved using alias template specialization:
///////////////////////////////////////////////////////////////
template<typename> using alias = std::set<T>;
template<> using alias<int> = std::vector<int>;
template<> using alias<double> = std::list<double>;
template<typename T> void foo()
{
alias<T> values;
}
The second example achieved using traits:
///////////////////////////////////////////////////////////////
template<typename> structNoDefaultAliasTrait;
template<> struct NoDefaultAliasTrait<int> {
using type = std::vector<int>;
};
template<> structNoDefaultAliasTrait<double> {
using type = std::list<double>;
};
template<typename T> void bar()
{
typename NoDefaultAliasTrait<T>::typevalues;
}
The second example achieved using alias template specialization and introducing ‘deletion’ of the generic alias template:
///////////////////////////////////////////////////////////////
template<typename> using no_default_alias= delete;
template<> using no_default_alias<int> = std::vector<int>;
template<> using no_default_alias<double> = std::list<double>;
template<typename T> void 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