我遇到了一些情況,我必須編寫兩個函數,其中一個函數應該用原始類型和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()
檢查是更多方便。
這個問題對我的口味有點主觀,但是你是否已經熟悉[檢測成語](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
@ildjarn我只聽說過關於hana,但不知道它 –
「更好」在哪些方面?你問是否有更好的'Is_string'特性實現?或者是否比首先使用一些'Is_string'特性更好的整體策略? – ildjarn