从 C++ 中的模板函数返回字符串和整数
Return both string and integer from a template function in C++
我正在尝试使用模板编写一个通用函数,该函数能够返回布尔值、整数或字符*或字符串。
template<typename entryType>
entryType getEntry(xml_node node, const char* entryKey)
{
...
if (is_same<entryType, bool>::value) {
return boolvalue; //returning a boolean
}
else if(is_same<entryType, int>::value) {
return a; //this is an integer
}
else if (is_same<entryType, char*>::value) {
return result; //this is a char*
}
}
我希望能够这样称呼它:
bool bPublisher = getEntry<bool>(node, "Publisher");
int QoS = getEntry<int>(node, "QualityOfService");
char* sBrokerUrl = getEntry<char*>(node, "BrokerUrl");
作为 char* 的替代方法,字符串也可以:
string sBrokerUrl = getEntry<string>(node, "BrokerUrl");
我收到这样的错误:"无法从'bool'转换为'char*'。我理解这个问题,编译器无法检测到代码执行分支取决于我给出的类型。我只是找不到解决方案。谁能帮我?谢谢。
从 C++17 开始,您可以使用 constexpr if; 其条件部分将在编译时被计算,如果结果是true
则语句假部分(否则为语句真部分(将被丢弃。(因此不会导致错误。例如
if constexpr (is_same<entryType, bool>::value) {
return boolvalue; //returning a boolean
}
else if constexpr (is_same<entryType, int>::value) {
return a; //this is an integer
}
else if constexpr (is_same<entryType, char*>::value) {
return result; //this is a char*
}
住
对于旧版本的C++,您可以通过转发到通过引用传递的参数返回结果的重载函数之一来解决此问题:
template<typename entryType>
entryType getEntry(xml_node node, const char* entryKey)
{
entryType result = entryType();
this->getEntry(node, entryKey, result);
return result;
}
void getEntry(xml_node node, const char* entryKey, bool& result);
void getEntry(xml_node node, const char* entryKey, int& result);
void getEntry(xml_node node, const char* entryKey, char const *& result);
或者您可以使用std::enable_if
(自 C++11 起(:
template<typename entryType>
typename std::enable_if<std::is_same<entryType, bool>::value, entryType>::type
getEntry(xml_node node, const char* entryKey) {
...
}
但第一个解决方案,IMO,更具可读性。如果您不想公开重载函数,则可以将其设为私有。
就像@tobi303评论中所说的那样,您应该专门化模板。 不需要花哨的SFINAE或其他技巧。
#include <iostream>
#include <type_traits>
using namespace std;
template<typename entryType>
entryType getEntry(const char* entryKey);
template <>
int getEntry<int>(const char* entryKey)
{
return 1;
}
template <>
bool getEntry<bool>(const char* entryKey)
{
return false;
}
template <>
string getEntry<string>(const char* entryKey)
{
return "asd";
}
int main() {
bool bPublisher = getEntry<bool>("Publisher");
int QoS = getEntry<int>("QualityOfService");
string sBrokerUrl = getEntry<string>("BrokerUrl");
cout << bPublisher << 'n' << QoS << 'n'<< sBrokerUrl << 'n';
}
演示:https://wandbox.org/permlink/kyLuPyblb4zBi9fE
如果您无法使用 C++17,模板专用化可能会执行您想要的操作:
template<typename entryType>
entryType getEntry(xml_node node, const char* entryKey) {}
template<>
bool getEntry<bool>(xml_node node, const char* entryKey) {
return true;
}
template<>
int getEntry<int>(xml_node node, const char* entryKey) {
return 1;
}
您可以将任何共享代码放在从每个专用化调用的帮助程序函数中:
void shared_code(xml_node node, const char* entryKey) {
// ...
}
template<>
bool getEntry<bool>(xml_node node, const char* entryKey) {
shared_code(node, entryKey);
return true;
}
template<>
int getEntry<int>(xml_node node, const char* entryKey) {
shared_code(node, entryKey);
return 1;
}
我想我倾向于利用std::tuple
已经非常出色的功能。
将其与标记值相结合,就可以以最小的努力为此类事情生成富有表现力的类型安全代码。
#include <iostream>
#include <tuple>
template<class Tag, class Type>
struct xmlvalue : Type
{
using Type::Type;
};
template<class Tag> struct xmlvalue<Tag, bool>
{
xmlvalue(bool v) : value_(v) {}
operator bool&() { return value_; }
operator bool const&() const { return value_; }
private:
bool value_;
};
template<class Tag> struct xmlvalue<Tag, int>
{
xmlvalue(int v) : value_(v) {}
operator int&() { return value_; }
operator int const&() const { return value_; }
private:
int value_;
};
struct is_publisher_tag {};
struct qos_tag {};
struct broker_url_tag {};
using is_publisher = xmlvalue<is_publisher_tag, bool>;
using qos = xmlvalue<qos_tag, int>;
using broker_url = xmlvalue<broker_url_tag, std::string>;
struct quote : std::tuple<is_publisher , qos, broker_url >
{
using std::tuple<is_publisher , qos, broker_url >::tuple;
};
int main() {
auto q1 = quote(true, 100, "http:://foo.com");
auto q2 = quote(false, 50, "http:://bar.com");
std::cout << std::get<broker_url>(q1) << ", " << std::get<qos>(q1) << ", " << std::get<is_publisher>(q1) << std::endl;
std::cout << std::get<broker_url>(q2) << ", " << std::get<qos>(q2) << ", " << std::get<is_publisher>(q2) << std::endl;
return 0;
}
预期输出:
http:://foo.com, 100, 1
http:://bar.com, 50, 0
相关文章:
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- C 字符串返回字符串的整数/双精度/长整型值
- 如何从COM模块中的函数返回字符串数组?
- React Native (Android):无法通过 JNI 在 jobject 中返回字符串
- 我如何在函数 cpp 中返回字符串
- 我有一个返回字符串向量的函数.它需要两个字符串,并且返回一个字符串中缺少的字符串
- 格式化返回字符串C++
- 返回字符串vs通过引用传递字符串以更新值
- 如何在不使用 STL 的情况下从函数反转字符串后返回字符串C++?
- 使用 ctypes 从函数返回字符串C++会给出大的 int,而不是 char 指针
- 从 C++ 中的模板函数返回字符串和整数
- 返回字符串的散点回文计数
- C++重载字符串 [] 运算符以返回字符串和
- 返回字符串和不同向量数据类型的映射C++
- 字符串函数不返回字符串? C++
- 从函数返回字符串C++错误
- 如何在返回字符串的函数中不忽略void值
- 我想将字符串转换为 Json 格式并返回字符串向量作为答案
- C - 返回字符串时的分割故障
- 使用向量和字符串函数返回字符串