2017-10-15 53 views
2

我遇到了一些情況,我必須編寫兩個函數,其中一個函數應該用原始類型和std::string調用。另一個應該用其他類型來調用。區分使用SFINAE和void_t的類型

template <typename...> 
struct Void_t_helper { 
    using type = void; 
}; 

template <typename... Ts> 
using Void_t = typename Void_t_helper<Ts...>::type; 


template <typename T, typename = void> 
struct Is_string : std::false_type {}; 

template <typename T> 
struct Is_string<T, Void_t<decltype (std::declval<T>().c_str())>> : std::is_same<decltype (std::declval<T>().c_str()), const char*>::type {}; 


template <typename T> 
std::enable_if_t<Is_string<T>::value || std::is_arithmetic<T>::value, void> foo (T) { 
    std::cout << "string or primitive\n"; 
} 

template <typename T> 
std::enable_if_t<!Is_string<T>::value && !std::is_arithmetic<T>::value, void> foo (T) { 
    std::cout << "other type\n"; 
} 

和使用:

到目前爲止,我有工作液結束

foo (1); 
foo (1.2); 
foo (std::string {"fsdf"}); 
foo (std::vector<int> {1, 2, 3}); 
foo (std::vector<std::string> {"a", "v", "c"}); 

產生預期:

string or primitive 
string or primitive 
string or primitive 
other type 
other type 

我的問題是:你知道更好解決這種問題?

我不確定如果檢查c_str()是否存在是我可以得到的更好的選擇。我知道我可能會寫一些包裝類,對於原始類型和std::string將有一些category_t定義爲值X,併爲其他類型的值Y和區分這些組使用這個類別,但我仍然認爲c_str()檢查是更多方便。

+0

這個問題對我的口味有點主觀,但是你是否已經熟悉[檢測成語](http://en.cppreference.com/w/cpp/experimental/is_detected)?和/或Boost.Hana的['is_valid'](http://www.boost.org/doc/libs/1_65_1/libs/hana/doc/html/structboost_1_1hana_1_1type.html#a2d2e7e08e284f7e0bd1bd9c3ad0e0a2b)? – ildjarn

+0

@ildjarn我只聽說過關於hana,但不知道它 –

+0

「更好」在哪些方面?你問是否有更好的'Is_string'特性實現?或者是否比首先使用一些'Is_string'特性更好的整體策略? – ildjarn

回答

6

我不確定是否檢查c_str()是否是我可以得到的更好的選項。

理想情況下,你會檢查你真正想要什麼。

可以是一組已知類型或模板,也可以是概念

此刻,您正在檢查「具有返回指向常量字符的指針的c_str()成員函數的概念」。

問題是,你的SFINAE的功能需要什麼概念?

如果它將使用c_str()成員,那是合理的。但是,如果要使用其他成員或字符串類型,則可能需要構建一個複合概念來描述要運行的界面的各個部分。

當然,您可能只是想確認它實際上是std::string的專業化版本。除非你陳述用例,否則很難說(不可能)。

+1

實際上選擇了'c_str()'是因爲它是'std :: string'的一部分,但不是'std :: vector'的一部分。我在這個問題中沒有提到這一點,這也是我問爲什麼有更好的選擇的原因。 –

+0

@ArturPyszczuk是的,我明白了。字符串幾乎是「向量樣」,除了像打印矢量一樣打印它,逐個元素是沒有意義的。當我在過去構建像這樣的過載發射器函數時,我已委派給部分專用的輸出器函子,而不依賴於過載選擇。 –

相關問題