2016-02-27 69 views
2

我正在玩proposal of standard library support for the C++ detection idiom。它是一種性狀狀元函數,其確定類型T是否有一個名爲T::type類型成員或具有特定簽名的成員函數,例如:使用檢測成語來確定某個類型是否具有特定簽名的構造函數

#include <iostream> 


template<class...> 
using void_t = void; 

template<class, template<class> class, class = void_t<>> 
struct detect : std::false_type { }; 

template<class T, template<class> class Operation> 
struct detect<T, Operation, void_t<Operation<T>>> : std::true_type { }; 


template<class T> 
using bar_t = decltype(std::declval<T>().bar()); 

template<class T> 
using bar_int_t = decltype(std::declval<T>().bar(0)); 

template<class T> 
using bar_string_t = decltype(std::declval<T>().bar("")); 


struct foo 
{ 
    int bar() { return 0; } 
    int bar(int) { return 0; } 
}; 


int main() 
{ 
    std::cout << detect<foo, bar_t>{} << std::endl; 
    std::cout << detect<foo, bar_int_t>{} << std::endl; 
    std::cout << detect<foo, bar_string_t>{} << std::endl; 

    return 0; 
} 

上述代碼產生預期的輸出

1 
1 
0 

你可以玩live demo。現在,我想測試一個T類型是否具有帶特定簽名的構造函數,例如T::T(U)與另一種類型U。使用檢測用語可以做到這一點嗎?

+1

出了什麼問題'的std :: is_constructible'? –

回答

2

修改detect類以允許可變參數ARGS:

template <typename...> 
using void_t = void; 

template <typename AlwaysVoid, template <typename...> class Operation, typename... Args> 
struct detect_impl : std::false_type { }; 

template <template <typename...> class Operation, typename... Args> 
struct detect_impl<void_t<Operation<Args...>>, Operation, Args...> : std::true_type { }; 

添加的別名硬編碼的空隙類型:

template <template <typename...> class Operation, typename... Args> 
using detect = detect_impl<void, Operation, Args...>; 
//       ~~~^ 

寫檢測器:

template <typename T, typename... Us> 
using has_constructor = decltype(T(std::declval<Us>()...)); 

測試你的課程:

static_assert(detect<has_constructor, foo, foo>{}, "!"); 

DEMO

2

更妙的是:std::is_constructible


template<class U> 
struct constructable_from { 
    template<class T> 
    using test_t = decltype(T(std::declval<U>())); 
}; 

// usage 
detect<foo, constructable_from<baz>::test_t> {} 

這似乎與你的代碼工作。可以很容易地擴展它以支持使用可變參數模板的多參數構造函數。我不知道這是否是「使用檢測成語」,但這是我以前一直在使用自己的東西。

test code on ideone(這是一個有點亂,我對移動)

相關問題