Я пытаюсь написать код, который сможет различать типы символов (char
, wchar_t
и т. Д.), Строковые типы (std :: string, std :: wstring и т. Д.) И числовые типы, так что я могу заключать символы в одинарные кавычки и строки в двойные кавычки. Идея состоит в том, чтобы обрабатывать значения по-разному в зависимости от того, как они выводятся. Символы и строки принципиально отличаются от числовых значений, потому что они отображаются в соответствии с представлением кодирования их содержимого (т. Е. ASCII, Unicode, UTF и т. Д.), А не в виде числовых значений.
(Примечание: этот код извлечен из гораздо более сложной и сложной программы)
Вот мой код, скомпилированный с
g++ -std=c++14 testchar.cpp -o testchar
, работающий под Linux Mint 18.3 (Sylvia), скомпилированный с g ++ v5.4.0
#include <iostream>
#include <locale>
#include <codecvt>
#include <string>
#include <type_traits>
using std::cout;
using std::is_same;
using std::string;
using std::u16string;
using std::u32string;
using std::wstring;
#define is_string_type(T) ( is_same<T,string>::value || is_same<T,wstring>::value || \
is_same<T,u16string>::value || is_same<T,u32string>::value )
#define is_char_type(T) ( is_same<T,char>::value || is_same<T,wchar_t>::value || \
is_same<T,char16_t>::value || is_same<T,char32_t>::value )
#define is_numeric_type(T) ( !is_char_type(T) && std::is_arithmetic<T>::value )
template <typename T>
typename std::enable_if<is_string_type(T),void>::type
output_value( const string& name, const T& strval ) {
cout << "String " << name << " is \"" << strval << "\";\n";
}
template <typename T>
typename std::enable_if<is_char_type(T),void>::type
output_value( const string& name, const T& chrval ) {
cout << "Character " << name << " is '" << chrval << "';\n";
}
template <typename T>
typename std::enable_if<is_numeric_type(T),void>::type
output_value( const string& name, const T& val ) {
cout << "Numeric " << name << " is " << val << ";\n";
}
int main(void)
{
string name;
short sval = 4321;
int ival = 123;
long lval = 1234567890L;
char cval = 'W';
string Sval = "string";
name = "sval";
output_value( name, sval );
name = "ival";
output_value( name, ival );
name = "lval";
output_value( name, lval );
name = "cval";
output_value( name, cval );
name = "strval";
output_value( name, Sval );
return 0;
}
Но мои макросы 'is_char_type' и 'is_string_type' некрасивы и не очень устойчивы. И они макросы ... хм! Я попытался использовать std::is_base_of<std::basic_string,T>::value
для `is_string_type ', но компилятор выдал ошибку:
testchar.cpp:17:65: error: type/value mismatch at argument 1 in template parameter list for ‘template<class, class> struct std::is_base_of’
Если кто-нибудь знает лучший способ сделать это, пожалуйста, дайте мне знать! Я немного удивлен, что эти (is_character_type
и is_string_type
) еще не существуют в type_traits
... или, может быть, они существуют, но умно замаскированы?