Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 获取C+;中所有类型和集合的调试字符串的通用函数+;_C++_Templates_Generics_Typetraits - Fatal编程技术网

C++ 获取C+;中所有类型和集合的调试字符串的通用函数+;

C++ 获取C+;中所有类型和集合的调试字符串的通用函数+;,c++,templates,generics,typetraits,C++,Templates,Generics,Typetraits,我想用C写一个泛型函数++ template<class T> string GetDebugString(const T& t); 模板 字符串GetDebugString(常量T&T); 它可以通用地获取所有类型的调试字符串。我的问题是如何使用特征来区分不同的类型: 1) 基本类型和字符串: 直接获取其字符串表示形式 2) 结构和类类型: 调用其“string DebugString()”方法。我将为所有类实现此方法。该方法可能会递归调用GetDebugString

我想用C写一个泛型函数++

template<class T>
string GetDebugString(const T& t);
模板
字符串GetDebugString(常量T&T);
它可以通用地获取所有类型的调试字符串。我的问题是如何使用特征来区分不同的类型:

1) 基本类型和字符串: 直接获取其字符串表示形式

2) 结构和类类型: 调用其“string DebugString()”方法。我将为所有类实现此方法。该方法可能会递归调用GetDebugString

3) 指针和智能指针: 取消对它们的引用并遵循1)或2)

4) 集合,如向量、集合或贴图: 迭代它的所有元素,获取1)、2)和3)之后每个元素的调试字符串,并以某些格式组装它们


我们如何使用std::enable_if做到这一点?

一种方法是使用专门化来编写特定于类型的实现。例如:

template<>
string GetDebugString(int& t)
{
   return "It's an int";
}

template<>
string GetDebugString(string& t)
{
   return t;
}

template <class T> 
string GetDebugString(T& t)
{
   //Now that you've taken care of the special cases
   //write a function to handle the generic

}
模板
字符串GetDebugString(int&t)
{
返回“它是一个整数”;
}
模板
字符串GetDebugString(字符串和t)
{
返回t;
}
模板
字符串GetDebugString(T&T)
{
//既然你已经处理好了特殊情况
//编写一个函数来处理泛型
}
大致如下:

#include <iostream>

#define AUTO_RETURN(...) -> decltype(__VA_ARGS__) {return (__VA_ARGS__);}

std::string GetDebugString(char ch) {return {ch};}
std::string GetDebugString(char const* str) {return str;}
std::string GetDebugString(std::string const& str) {return str;}

template <typename T>
auto GetDebugString( T t ) AUTO_RETURN(std::to_string(t))

// No AUTO_RETURN here because of GCC
template <typename T>
auto GetDebugString( T ptr ) -> decltype(GetDebugString(*ptr))
{
    return "Pointer to " + GetDebugString(*ptr);
}

template <typename T>
auto GetDebugString( T&& t ) AUTO_RETURN(std::forward<T>(t).DebugString())

template <typename T, typename U>
auto GetDebugString( std::pair<T, U> const& p ) AUTO_RETURN('<' + GetDebugString(p.first) + ',' + GetDebugString(p.second) + '>')

template <typename Range>
auto GetDebugString( Range&& c ) -> decltype(std::begin(c), std::end(c), std::string())
{
    // Size obtainment can be optimized for containers with size member-functions
    std::string str = "Range with " + std::to_string(std::distance(std::begin(c), std::end(c))) + " elements: \n\t";
    for (auto const& elem : c)
        str += GetDebugString(elem) + ", ";
    return str;
}

int main()
{
    int i = 23;
    auto ptr = &i;
    char const str[] = "Hallo!";
    auto list = {4, 5, 5, 6, 8};

    std::cout << GetDebugString(i) << '\n';
    std::cout << GetDebugString(ptr) << '\n';
    std::cout << GetDebugString(str) << '\n';
    std::cout << GetDebugString(list) << '\n';
}
#包括
#定义自动返回(…)->decltype(uu VA_ARGS_uuu){RETURN(u VA_ARGS_uuu)}
std::string GetDebugString(char ch){return{ch};}
std::string GetDebugString(char const*str){return str;}
std::string GetDebugString(std::string const&str){return str;}
模板
自动GetDebugString(T)自动返回(std::to_字符串(T))
//由于GCC,此处没有自动返回
模板
自动GetDebugString(T ptr)->decltype(GetDebugString(*ptr))
{
返回“指向”+GetDebugString(*ptr)的指针;
}
模板
自动获取调试字符串(T&&T)自动返回(std::forward(T).DebugString()
模板
自动获取调试字符串(std::pair const&p)自动返回(“”)
模板
auto-GetDebugString(Range&&c)->decltype(std::begin(c)、std::end(c)、std::string()
{
//尺寸获取可以针对具有尺寸成员功能的容器进行优化
std::string str=“带“+std::to_string(std::distance(std::begin(c),std::end(c)))+”元素的范围:\n\t”;
用于(自动常量和元素:c)
str+=GetDebugString(elem)+“,”;
返回str;
}
int main()
{
int i=23;
自动ptr=&i;
char const str[]=“你好!”;
自动列表={4,5,5,6,8};

std::您可以使用SFINAE检查您是否正在使用
DebugString
方法处理类型,以及是否正在重载您提到的所有内容。无需任何特征。如果您搜索这些术语,您应该能够复制/抓取一些内容,并就特定问题寻求帮助。这可以帮助您:@TonyD That将是我也会选择的方向。重载选择3和4(因为它们更专业),然后使用SFINAE来区分1和2。(FWIW:我也会为字符串提供一个特殊的重载,因为我想把它们放在引号中,并且可能在必要时插入转义序列。否则,中间的一个字符串可能会导致一些非常混乱的输出。)您还可以告诉我如何处理map吗?@Fake为
pair
s添加了一个重载。谢谢。那么是否可以为map单独设置一个GetDebugString?