C++ template alias (using) in specific places

旧街凉风 提交于 2021-01-27 04:34:29

问题


I need to use type aliases via using (or any other method) in situations like this:

template <class T>
typename std::enable_if< /*HERE*/>::value
f (...) {};

Where I wrote HERE there are long and more than one types defined inside structures, and instead of writing typename <very long templated struct dependent on T>::type I want to write a shortcut.

And I encountered this in more situations like template specializations and suffix return type syntax. So Is there any way of using using (no pun intended) in places between the first line template <...> and the struct/class or function?.

I have tried using , (comma) something like (using X = ... , /*actually using X*/) without success.

What worked was a global scoped using

template <class Iterator>
using DT = typename DereferenceType<Iterator>::type&;

but I don't want global scope, I want the scope to be just for the template I use it. And I don't want to write DT<Iterator>, just DT.

Needless to say macros or any preprocessor directives are out of the question.


Real life example:

template <class Iterator, class GetCompValue, class SortOrder = Ascending>
typename std::enable_if<
    IsDereferenceable<Iterator>::value &&
    IsCallableLike<GetCompValue,
                   typename DereferenceType<Iterator>::type&(
                      typename DereferenceType<Iterator>::type&)>::value &&
    IsSortOrder<SortOrder>::value, void>::type
RadixSortLSDByteOffsetIter(Iterator first, Iterator last,
                           GetCompValue get_comp_value, SortOrder = kAscending) {

Here I want a shortcut for typename DereferenceType<Iterator>::type& something like:

template <class Iterator, class GetCompValue, class SortOrder = Ascending>
// using DT = typename DereferenceType<Iterator>::type&;
typename std::enable_if<
    IsDereferenceable<Iterator>::value &&
    IsCallableLike<GetCompValue, DT(DT)>::value &&
    IsSortOrder<SortOrder>::value, void>::type
RadixSortLSDByteOffsetIter(Iterator first, Iterator last,
                           GetCompValue get_comp_value, SortOrder = kAscending) {

Thank you.


回答1:


C++14 will solve your problem by introducing variable templates:

template <typename T>
T one_half = T(1) / T(2);

template <typename A, typename B>
bool is_base_of_v = std::is_base_of<A, B>::value;

Usage:

std::cout << one_half<double> << "\n" << is_base_of_v<Foo, Bar> << "\n";

So you'll be able to make your HERE into a boolean-valued variable template.


Unrelatedly, another way to clean up your traits is to get rid of the typename ...::type, like so:

template <typename C, typename T = void>
using enable_if_t = typename std::enable_if<C, T>::type;

Now you can use:

template <typename T> enable_if_t<my_condition<T>> f() { /* ... */ }



回答2:


Why don't you just alias by defining new types?

struct alias : long-long-typename {}


来源:https://stackoverflow.com/questions/20800658/c-template-alias-using-in-specific-places

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!