[問題] string 測試 operator += 有沒有存在

作者: hare1039 (hare1039)   2018-07-15 22:26:02
開發平台(Platform): (Ex: Win10, Linux, ...)
Arch Linux
編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
clang 6.0.0
g++ 7.3.1
額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
None
問題(Question):
最近在自學 C++ meta programming,碰到這個問題:
測試一個 type 能不能正確的被 std::string += 起來
目前的解法是:
template<typename T>
struct can_string_cat_impl
{
template <typename Operand> // SFINAE out if += not working
static auto test(Operand o) -> decltype(std::declval<std::string>() += o);
template <typename...>
static auto test(...) -> std::false_type;
using type = typename std::is_same<std::string, std::decay_t<decltype(test(std::declval<T>()))>>::type;
};
template <typename T>
struct can_string_cat : can_string_cat_impl<T>::type {};
現在的 code 已經可以做到一部分了,但是因爲 int / long / double 等等可以隱式轉型成 char
因此 can_string_cat<V>::value 會說上面這些 type 是可以 += 的
但是很明顯的,casting 過後,再 += 的結果不是正確的
e.g.
std::string s{"hello "};
int x = 100;
s += x; // s 要是 "hello 100" 而不是 "hello d"
目前想到的解法有
1: 想辦法取消隱式轉型
2: 把所有有可能隱式轉型成 char 的 type 全部寫出來,test<int>(), test<double>...
讓 compiler 不會選到 template <typename Operand> 的 overload
1 的話現行 C++ 應該是無解
2 的話就像是硬刻 99 乘法表一樣,難以維護
想請問高手們有沒有更好的解決辦法?
謝謝
餵入的資料(Input):
None
預期的正確結果(Expected Output):
string can += on PKc
string cannot += on St6vectorIiSaIiEE
string cannot += on i
string cannot += on l
string cannot += on d
錯誤結果(Wrong Output):
string can += on PKc
string cannot += on St6vectorIiSaIiEE
string can += on i
string can += on l
string can += on d
程式碼(Code):(請善用置底文網頁, 記得排版,禁止使用圖檔)
https://gist.github.com/hare1039/a94a36be97e6b30d46d4affca60fe833
補充說明(Supplement):
using compiler flag: -O3 -std=c++17 -Wall -Wextra
感謝各路高手幫忙 m(_o_)m
作者: hare1039 (hare1039)   2018-07-16 13:45:00
感謝 A 大,目前看起來去掉數字 type 還滿不錯的
作者: AstralBrain   2018-07-16 00:10:00
判斷條件加上 (not is_arithmetic_v<T> oris_same_v<T, char>)這樣至少可以排除掉char以外的數字type
作者: ibmibmibm (BestSteve)   2018-07-17 16:38:00
記得char,unsigned char, signed char都是不同型態

Links booklink

Contact Us: admin [ a t ] ucptt.com