使用模板将类型发送到函数中
Posted
技术标签:
【中文标题】使用模板将类型发送到函数中【英文标题】:Send type into function using templates 【发布时间】:2021-02-04 07:54:06 【问题描述】:我有这个函数可以在 map 中查找键并返回正确的值:
template< typename T >
T Foo::findInMap(std::string key)
std::map<std::string, std::any>::iterator it = options.find(key);
if (it != options.end())
return std::any_cast<T>(it->second);
return nullptr;
地图如下所示:
std::map<std::string, std::any> options;
如何调用和修改函数以充分利用 C++17?
【问题讨论】:
这不是 C++17 而是“C++98”:您也许可以将标准构造的 T 变量的地址提供给查找函数,而不是按值返回它。因此,可以使用 bool 返回而不是nullptr
,由于当前的返回类型规范(可能是错字?),这也将不起作用。
std::optional
是 C++17
这不是代码审查,我是 c++17 的新手
【参考方案1】:
返回nullptr
并不总是可行的。返回可选值的现代 C++ 方法是使用std::optional
。您可以使用 auto
代替长迭代器类型名称。这是您可以做到的一种方法:
template< typename T >
std::optional<T> findInMap(std::string key)
auto const it = options.find(key);
if (it != options.end())
return std::optional<T> std::any_cast<T>(it->second) ;
return std::nullopt;
【讨论】:
你能说明一下如何调用它吗? 如果想要“完整的 C++17”,那么std::optional
的 CTAD 也是可能的。而it
可以在if
的可选init 语句中定义。
非常感谢。虽然我仍然认为如果包括在内,这不会损害您的答案:-)【参考方案2】:
对于同时声明和初始化,std::optional 可能会提供更好的方法。但是在任何情况下,类型可变性和可选性都会影响上下文(阅读:调用和案例区分)。我决定承担使用默认初始化的变量加载周围范围的成本,以便在找到的情况下随后被覆盖。这样我就得到了一个函数调用,它的参数决定了类型,使得调用者不需要尖括号中的类型说明。
我还将函数重命名为map_assign
(删除了成员函数状态,因为这里不相关):
template< typename T >
bool map_assign(const std::string& key, T* value)
auto it = options.find(key);
if (it != options.end())
*value = std::any_cast<T>(it->second);
return true;
return false;
你可以这样称呼它:
std::string value;
if (map_assign("somekey", &value))
// found case
else
// not-found case
【讨论】:
谢谢,为什么要在 any_cast 中使用指针?我可以在没有指针的情况下通过 ref 返回就好了 谢谢,我还修复了一个问题。我本可以通过引用来实现它,但这只是一个风格细节,并且我个人经历了一个高度依赖于引用的阶段,我目前更倾向于指针版本。【参考方案3】:any_cast(T&) 抛出 std::bad_any_cast,改用 any_cast(const T*)
struct Test
template <typename T>
std::optional<T> findInMap(std::string key)
if (auto it = options.find(key); it != options.end())
if(auto ptr = std::any_cast<T>(&it->second); ptr)
return std::make_optional<T>(*ptr);
return std::nullopt;
std::map<std::string, std::any> options;
;
【讨论】:
以上是关于使用模板将类型发送到函数中的主要内容,如果未能解决你的问题,请参考以下文章
图片不会在我的 Alamofire .post 请求中发送到我的后端 - Swift 3