gpt4 book ai didi

c++ - 用于自由函数包装器的 SFINAE 技术

转载 作者:太空狗 更新时间:2023-10-29 23:33:06 28 4
gpt4 key购买 nike

我真的很希望能够有一个免费的函数来适应它被给定的任何类型。

例如

template <typename T> bool ReadLine(T & reader, std::string & line) 
{
return reader.ReadString(line);
}

对于某些 T,正确的函数是 reader.ReadString(buffer)。但对于其他人来说,它应该是 reader.ReadLine(buffer)。当然, future 可能还会有其他模式。重点是调整自由函数 ReadLine(from, into) 以使用任何合理的 from & into 集(我强制目标缓冲区为 std::string 以简化这里的事情)。

现在,我可以为我想要的任何具体类型制作一个非模板版本的 ReadLine,但我真正需要的是能够部分专门化类型的类,例如那些支持模式 reader.ReadString()所有最终都使用它,那些支持 reader.ReadLine() 的使用它,将来我可以添加其他模式而不会干扰任何已经工作的东西。

我知道我可以创建一个策略类,例如 LineReaderPolicy,它知道对于给定的 T 要使用哪种模式(它必须根据 T 进行部分特化才能将其映射到正确的模式。

但是否有更好、更符合 C++14 的方法来解决这个问题?

这是其中之一“上帝啊,模板似乎真的非常非常接近真正非常有用……但是对于这个不断重复出现的问题……”

C++11/14 的可堆肥性比以往任何时候都好,但这个基本问题似乎仍未解决?或者是?!

你会如何建议我编写一组自由函数来适应任何合理的 T 以从中读取一行? T 是否是字符串流、输出迭代器、文件句柄、字符串、字符串 View 等...

在我能写出一个合理的程序之前,我不能认为 C++ 真的成熟了

template <typename T> size_t length(T t) { return t.size(); }

然后我可以将其扩展到任何合理的 T,而不必编写了解 T 如此多细节的代码,而是可以通过这种灵活的自由函数适配器与大量 T 进行互操作...

最佳答案

如果您可以确保最多定义了 reader.ReadStringreader.ReadLine 之一,请使用 SFINAE 控制重载 ( Live at Coliru ):

template <typename T>
auto ReadLine(T& reader, std::string& line) -> decltype(reader.ReadString(line)) {
return reader.ReadString(line);
}

template <typename T>
auto ReadLine(T& reader, std::string& line) -> decltype(reader.ReadLine(line)) {
return reader.ReadLine(line);
}

不适用的实现将触发 SFINAE 并从重载集中删除,只留下正确的实现。

在 C++14 中,您将能够省略尾随返回类型并简单地使用返回类型推导。

在 C++ 的 future 修订版中,Concepts Lite将使这可以更干净地完成。给定区分两种不同类型阅读器的概念 - 例如 StringReaderLineReader:

template <typename T>
concept bool StringReader() {
return requires(T& reader, std::string& line) {
{reader.ReadString(line)} -> bool;
};
}

template <typename T>
concept bool LineReader() {
return requires(T& reader, std::string& line) {
{reader.ReadLine(line)} -> bool;
};
}

您将能够直接将您的实现限制为对这些概念建模的类型集:

bool ReadLine(StringReader& reader, std::string& line) {
return reader.ReadString(line);
}

bool ReadLine(LineReader& reader, std::string& line) {
return reader.ReadLine(line);
}

希望您能够在其他地方重用这些概念,以证明“new-special-better”语法比旧的讨厌语法长得多。 Concepts Lite 还可以通过显式消除歧义来处理对两个 概念建模的类型:

template <typename T>
requires StringReader<T>() && LineReader<T>()
bool ReadLine(T& reader, std::string& line) {
// Call one, or the other, or do something completely different.
}

关于c++ - 用于自由函数包装器的 SFINAE 技术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22409356/

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