为成员模板静态函数键入trait

时间:2016-03-23 06:01:18

标签: c++ templates c++11 sfinae

我在C ++中遇到类型特征问题。我习惯于进行SFINAE检查以确保功能存在与否。但是,我想知道一个类是否具有特定的模板成员静态函数。

这个例子有助于解释我的问题。让我们假装doMake函数将函数指针作为参数,将其参数作为包。

struct A {
    static A construct(int mA, double mB) {
        return A{mA, mB};
    }

    int a;
    double b;
};

struct B {
    // silly but some of my code need this
    template<typename T>
    static B construct(int mA, T mB) {
        return B{mA, mB};
    }

    int a;
    double b;
};

struct Container {
    // function (1)
    template<typename T, typename... Args,
        typename std::enable_if<has_template_construct<T>::value, int>::type = 0>
    T make(Args&&... args) {
        return doMake(&T::construct<Args...>, std::forward<Args>(args)...);
    }

    // function (2)
    template<typename T, typename... Args,
        typename std::enable_if<has_construct<T>::value, int>::type = 0>
    T make(Args&&... args) {
        return doMake(&T::construct, std::forward<Args>(args)...);
    }

    // function (3)
    template<typename T, typename... Args,
        typename std::enable_if<!has_construct<T>::value, int>::type = 0>
    T make(Args&&... args) {
        return T{std::forward<Args>(args)...};
    }
};

// ...

int main() {
    Container c;
    auto a = c.make<A>(1, 5.7); // would call (2)
    auto b = c.make<B>(2, 5.8); // would call (1)
    auto d = C.make<float>(4.f); // obviously call the last
    return 0;
}

我知道如何实施has_construct,但我对如何实施has_template_construct感到很遗憾。有人可以给我一些提示吗? 谢谢!

1 个答案:

答案 0 :(得分:3)

您可以使用实验is_detected

template<class T>
using construct_t = decltype(&T::construct);

template<class T, typename...Ts>
using template_construct_t = decltype(&T::template construct<Ts...>);

template <typename T>
using has_construct = is_detected<construct_t, T>;

template <typename T, typename...Ts>
using has_template_construct = is_detected<template_construct_t, T, Ts...>;

请注意,在 function1 中,您必须使用has_template_construct<T, Args...>::value,Args...已添加)。