2016-03-23 68 views
2

我在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丢失。有人可以给我一些提示吗? 谢谢!

+0

为什么不像'decltype(&T :: template construct )'那样使用表达式SFINAE? – Jamboree

回答

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...>; 

注意,在功能1,你将不得不使用has_template_construct<T, Args...>::value,Args...添加)。

相关问题