我有一个程序,它使用 json-glib 为 ReST Server 创建一个 JSON 文件。该文件有2个字段,即id
和value
。id
只是std::string
但值可以是整数、布尔值、字符串(通过std::string
odchar const *
)或浮点数,具体取决于要传输的值。我在功能和char *
方面遇到麻烦c.str()
.
if(std::is_integral<T>::value)
{
if(std::is_same<T, bool>::value)
{
if(json_builder_add_boolean_value (builder, tagValue) == nullptr)
{
returnMessage = string("json_builder_add_boolean_value was inconsistent in setTag(Boolean). TagName : ") + tagName + string("TagValue : ") + to_string(tagValue);
#ifdef __DEBUG
cerr << returnMessage;
#endif
return false;
}
}
else
{
if(json_builder_add_int_value (builder, tagValue) == nullptr)
{
returnMessage = string("json_builder_add_int_value was inconsistent in setTag(Int). TagName : ") + tagName + string("TagValue : ") + to_string(tagValue);
#ifdef __DEBUG
cerr << returnMessage;
#endif
return false;
}
}
}
else if(std::is_floating_point<T>::value)
{
if(json_builder_add_double_value (builder, tagValue) == nullptr)
{
returnMessage = string("json_builder_add_double_value was inconsistent in setTag(Double). TagName : ") + tagName + string("TagValue : ") + to_string(tagValue);
#ifdef __DEBUG
cerr << returnMessage;
#endif
return false;
}
}
else if(std::is_same<T, string>::value or std::is_same<T, const string>::value)
{
if(json_builder_add_string_value (builder, tagValue.c_str()) == nullptr)
{
returnMessage = string("json_builder_add_string_value was inconsistent in setTag(String). TagName : ") + tagName + string("TagValue : ") + to_string(tagValue);
#ifdef __DEBUG
cerr << returnMessage;
#endif
return false;
}
}
else if(std::is_same<T, char *>::value or std::is_same<T, const char *>::value)
{
if(json_builder_add_string_value (builder, tagValue) == nullptr)
{
returnMessage = string("json_builder_add_string_value was inconsistent in setTag(String). TagName : ") + tagName + string("TagValue : ") + to_string(tagValue);
#ifdef __DEBUG
cerr << returnMessage;
#endif
return false;
}
}
错误:请求"tagValue"中的成员"c_str",该成员的非类类型为"int" if(json_builder_add_string_value (builder, tagValue.c_str()) == nullptr)
错误:从"int"到"const gchar* {aka const char*}" [-permissive] 的转换无效
我正在使用 C++14
可惜了。 你不能使用if constexpr
这是你的问题的自然解决方案,但它是从 C++17 开始引入的。
无论如何,如果没有if constexpr
,编译器必须编译函数的每个部分;所以如果你的tagValue
是一个bool
,编译器也必须编译不可用于bool
的tagValue.c_str()
调用。
所以错误。
在C++17之前,您必须为不同类型的功能开发不同的功能。
一个可能的解决方案是使用重载和SFINAE为三种确切的类型(bool
,std::string const &
和char const *
)定义三个非模板foo()
函数。
void foo (std::string const & id, bool value)
{
// json_builder_add_boolean_value, etc
std::cout << "-- bool case: " << id << ", " << value << std::endl;
}
void foo (std::string const & id, std::string const & value)
{
// json_builder_add_string_value, etc
std::cout << "-- std::string case: " << id << ", " << value << std::endl;
}
void foo (std::string const & id, char const * value)
{
// json_builder_add_string_value, etc
std::cout << "-- char * case: " << id << ", " << value << std::endl;
}
和两个模板foo()
函数,通过 SFINAE 为整型类型(第一个)和浮点类型(第二个)启用
template <typename T>
std::enable_if_t<std::is_integral<T>{}>
foo (std::string const & id, T const & value)
{
// json_builder_add_int_value, etc
std::cout << "-- integral case: " << id << ", " << value << std::endl;
}
template <typename T>
std::enable_if_t<std::is_floating_point<T>{}>
foo (std::string const & id, T const & value)
{
// json_builder_add_double_value, etc
std::cout << "-- floating case: " << id << ", " << value << std::endl;
}
所以打电话
foo("1", false);
foo("2", 0L);
foo("3", 0.0f);
foo("4", std::string{"zero"});
foo("5", "zero");
你得到
-- bool case: 1, 0
-- integral case: 2, 0
-- floating case: 3, 0
-- std::string case: 4, zero
-- char * case: 5, zero
请注意,bool
是整型,因此可以匹配foo()
模板整型版本和foo()
bool
特定版本。
在这种情况下,首选完全匹配,因此调用bool
特定版本。