使用模板将类型发送到函数中

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

使用一个策略之一将记录发送到消息队列

*通过 *100 台相机在 1 中发送到 Instagram* 技巧*

如何在iOS5中发送电子邮件到后台的收据?

如何使用 groovy 模板在 Jenkins 中发送电子邮件?