2016-03-23 105 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...添加)。

相關問題