Why can't I add a layer of abstraction with type lookup to strip references in C++?

懵懂的女人 提交于 2019-12-11 15:49:40

问题


This is kind of a followup question to

Why can't I use traits with forwarding references in C++?

which has been correctly answered. However I tried my own solution below

https://godbolt.org/z/X7dBz1

#include <type_traits>

template <typename T, typename enable = void> struct Traits {
    static const bool value = false;
};

template <typename T> struct Traits<T,std::enable_if<std::is_reference<T>::value>> {
    static const bool value = Traits<typename std::remove_reference<T>::type>::value;

};

struct Zip{};
template <> struct Traits<Zip,void> {
    static const bool value = true;
};

template <typename E>
void Execute(E && e){
    static_assert(Traits<E>::value);
}

int main(){
    auto z = Zip();
    Execute(z);
}

the theory being that if the correct specialisation fails then the next most specialized will be the one that matches based on if T is a reference. If this matches then the reference is stripped and we recurse hopefully getting a match. But this does not seem to work. Is there a way to fix this that keep the spirit of my attempt?


回答1:


You are misusing std::enable_if. As written, your Traits struct is specialized on std::enable_if itself, not its result. You need to access the nested ::type type alias:

typename std::enable_if<std::is_reference<T>::value>::type
// or
std::enable_if_t<std::is_reference<T>::value>

live example on godbolt.org




回答2:


N.B. you can also do it without enable_if (looks cleaner, IMO):

template <typename> struct Traits {
    static const bool value = false;
};

template <typename T>
struct Traits<T&> : Traits<T> {};

template <typename T>
struct Traits<T&&> : Traits<T> {};


来源:https://stackoverflow.com/questions/53742648/why-cant-i-add-a-layer-of-abstraction-with-type-lookup-to-strip-references-in-c

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