简体   繁体   English

缺少类型的模板函数(在运行时未使用)函数

[英]Template function with type thats missing (unused in run-time) function

Say i got template function like this 说我有这样的模板功能

template <typename T> bool func(T a)
{
  if(a.X())
    return a.Y();
  return false;
}

Now every class i use as parameter to this function has function X(), but not every class i use as parameter has function Y(). 现在我用作此函数的参数的每个类都有函数X(),但不是我用作参数的每个类都有函数Y()。 However if function aX() returns true then i have guaranteed that given class has function Y(). 但是,如果函数aX()返回true,那么我保证给定的类具有函数Y()。 Can i make this code compile somehow since i know that function Y() which compiler is whining about missing on certain types will never be called? 我可以以某种方式编译此代码,因为我知道函数Y()哪个编译器抱怨某些类型的缺失永远不会被调用? This function is in reality really big and types used are many so making a number of specializations is impractical. 这个功能实际上非常大,使用的类型很多,所以制作一些专业是不切实际的。

SFINAE may help, something like: ( https://ideone.com/XmjQY8 ) SFINAE可能有所帮助,例如:( https://ideone.com/XmjQY8

#include <type_traits>
#include <cstdint>

#define DEFINE_HAS_SIGNATURE(traitsName, funcName, signature)               \
    template <typename U>                                                   \
    class traitsName                                                        \
    {                                                                       \
    private:                                                                \
        template<typename T, T> struct helper;                              \
        template<typename T>                                                \
        static std::uint8_t check(helper<signature, &funcName>*);           \
        template<typename T> static std::uint16_t check(...);               \
    public:                                                                 \
        static                                                              \
        constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t); \
    }

DEFINE_HAS_SIGNATURE(has_X, T::X, bool (T::*)());
DEFINE_HAS_SIGNATURE(has_Y, T::Y, bool (T::*)());

template <typename T>
typename std::enable_if<has_X<T>::value && has_Y<T>::value, bool>::type
func(T a)
{
  if(a.X())
    return a.Y();
  return false;
}

template <typename T>
typename std::enable_if<!has_X<T>::value || !has_Y<T>::value, bool>::type
func(T /*a*/)
{
    return false;
}

Here is another version inspired by this answer which is a little shorter (and nicer in my opinion :) ). 这是另一个灵感来自这个答案的版本,它有点短(在看来更好:))。

struct Action
{
    template <typename T>
    static bool func_real(T a){return func(a, special_());}

private:

    struct general_ {};
    struct special_ : general_ {};
    template<typename> struct bool_ { typedef bool type; };

    template<typename S, typename bool_<decltype(std::declval<S>().Y())>::type = 0>
    static bool func(S a, special_) {
        cout<<"Y() exists"<<endl;
        if(a.X()){
            return a.Y();
        }
        return false;
    }

    template<typename S>
    static bool func(S a, general_) {
        cout<<"Y() does not exist"<<endl;
        return false;
    }
};

Here is a live demo. 是一个现场演示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM