gpt4 book ai didi

c++ - 如何检查模板类型参数是字符类型还是字符串类型?

转载 作者:行者123 更新时间:2023-11-28 01:31:54 26 4
gpt4 key购买 nike

我正在尝试编写能够区分字符类型(charwchar_t 等)、字符串类型(std::string、std::wstring 等)和数字类型的代码,所以我可以将字符括在单引号中,将字符串括在双引号中。这个想法是根据值的输出方式对值进行不同的处理。字符和字符串从根本上不同于数值,因为它们根据其内容的编码表示(即 ASCII、Unicode、UTF 等)而不是数值显示。

(注意:这段代码是从一个更大更复杂的程序中提取出来的)

这是我的代码,用

编译
g++ -std=c++14 testchar.cpp -o testchar

在使用 g++ v5.4.0 编译的 Linux Mint 18.3 (Sylvia) 下运行

#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_typeis_string_type )在 type_traits 中并不存在……或者它们可能存在,但被巧妙地伪装了?

最佳答案

template<class T>struct tag_t{};
template<class T>constexpr tag_t<T> tag{};
namespace detect_string {
template<class T, class...Ts>
constexpr bool is_stringlike(tag_t<T>, Ts&&...){ return false; }
template<class T, class A>
constexpr bool is_stringlike( tag_t<std::basic_string<T,A>> ){ return true; }
template<class T>
constexpr bool detect=is_stringlike(tag<T>); // enable ADL extension
}
namespace detect_character {
template<class T, class...Ts>
constexpr bool is_charlike(tag_t<T>, Ts&&...){ return false; }
constexpr bool is_charlike( tag_t<char> ){ return true; }
constexpr bool is_charlike( tag_t<wchar_t> ){ return true; }
// ETC
template<class T>
constexpr bool detect=is_charlike(tag<T>); // enable ADL extension
}

现在detect_character::detect<char>true ,原样 detect_string::detect<std::wstring> .

如果您只想将 charlike 的字符串作为字符串,请将其添加到 is_stringlike过载。

您可以通过在类型 X 的命名空间中定义 is_stringlike(tag_t<X>) 来扩展其中任何一个。过载,它会被自动发现。或者在 detect_stringlike 中这样做.您不能向 std 添加重载这样,他们在detect_stringlike中也是如此命名空间。

还有其他解决方案,但这是唯一避免单一中央列表脆弱性的解决方案。

关于c++ - 如何检查模板类型参数是字符类型还是字符串类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51128745/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com