gpt4 book ai didi

C++模板元编程(17以下版本,最好是11)

转载 作者:行者123 更新时间:2023-11-28 04:02:08 24 4
gpt4 key购买 nike

我有一些 C++ 和 std 库经验,甚至写过几个简单的模板函数,但与许多其他人一样,模板元编程似乎让我大吃一惊。

我想生成一个模板化函数,用于解析 std::string 以获得小范围的合法值。它需要根据在字符串中找到的内容返回不同的类型,或者如果字符串不匹配任何合法形式则返回错误代码。例如有效的字符串可以是:

  • a) 数字单值,例如“42”
  • b) 单个非数字字符串,例如“任何东西”
  • c) a) 的逗号分隔列表,例如“13,42,666”
  • d) b) 的逗号分隔列表,例如“你想要的任何东西”

不同的实例化会“预期”某种类型并在匹配失败时产生错误,例如,如果我想要 c) 并找到其他有效的 d) then: error,反之亦然。显然,当找到有效的匹配项时,每个匹配项的返回类型都会不同。

我认为返回值应该是 pair<uint32_t errorcode,T>其中 T 是:

  • a) uint32_t
  • b) std::string
  • c) std::vector<uint32_t>
  • d) std::vector<std::string>

在最高的抽象层次上,我想做的是:

实例化1:

如果(期望数字 &&(数字或数字列表)) f( n | n1,n2,n3...)否则错误

实例化2:

if(期待字符串 && (字符串或字符串列表)) f( s | s1,s2,s3...)否则错误

我想我需要 #include <type_traits>可能还有 std::is_arithmetic,但我只是无法“理解”根据预期类型是否为数字来“分支”模板的概念和语法。

更具体地说,我从以下内容开始:

template<typename ReturnType, typename Expected>
pair<uint32_t,ReturnType> parseInput(std::string input,std::function<void(ReturnType)> f){
if(!initalvalidation(input)) return std::make_pair<999, ? >; // Exclude total garbage... ? = don't care as long as its a valid ReturnType

/*compile-time-if ?? */ *if* is_numeric(Expected){
ReturnType result;
result=parseInputForNumbers(input); // will return an empty ReturnType if invalid
return make_pair<(result.size() > 0 ? 0:123),result>; // 123 = bad numeric format
// obvs that won't work for uint32_t as it has no size() function, so again...HOW?
}
else {
... similar for strings
}
}

我知道它看起来不像 if/else block ,但这是我能解释它的唯一方式!

最后,我不需要解析、如何在运行时确定某物是否为数字等方面的帮助。我只需要有关模板函数的结构/语法的帮助和建议。

最佳答案

我真的不明白这里模板的意义:
其他一些想法怎么样?

你可能有:

enum class Error; // Or dedicated class or use std::optional

std::variant<std::uint32_t, Error> ParseUInt32(const std::string& s);
std::variant<std::string, Error> ParseString(const std::string& s);
std::variant<std::vector<std::uint32_t>, Error> ParseUInt32s(const std::string& s);
std::variant<std::vector<std::string>, Error> ParseStrings(const std::string& s);

如果你想有相同的名字来简化模板代码,你可以添加重载:

template <typename T> struct Tag {};

auto Parse(Tag<std::uint32>, const std::string& s) { return ParseUInt32(s); }
auto Parse(Tag<std::string>, const std::string& s) { return ParseString(s); }
auto Parse(Tag<std::vector<std::uint32_t>>, const std::string& s) { return ParseUInt32s(s); }
auto Parse(Tag<std::vector<std::string>>, const std::string& s) { return ParseStrings(s); }

因此,您可能有一个“通用”的:

std::variant<std::uint32_t,
std::string,
std::vector<std::uint32_t>,
std::vector<std::string>,
Error>
Parse(const std::string& s)
{
auto v1 = ParseUInt32s(s);
if (auto* res = std::get_if<std::vector<std::uint32_t>>(v1)) {
return std::move(*res);
}

auto v2 = ParseStrings(s);
if (auto* res = std::get_if<std::vector<std::string>>(v2)) {
return std::move(*res);
}

auto v3 = ParseUInt32(s);
if (auto* res = std::get_if<std::uint32_t>(v3)) {
return *res;
}

auto v4 = ParseString(s);
if (auto* res = std::get_if<std::string>(v4)) {
return std::move(*res);
}
return Error::InvalidInput;
}

注意:对于 C++11,Boost 等效于 std::variant/std::optional

关于C++模板元编程(17以下版本,最好是11),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59334977/

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