调用此模板时如何避免使用 decltype?

Posted

技术标签:

【中文标题】调用此模板时如何避免使用 decltype?【英文标题】:How can I avoid having to use decltype when calling this template? 【发布时间】:2020-07-24 18:38:02 【问题描述】:

我有以下代码,用于自动捕获bad_variant_access 错误。我知道我可以使用get_if 来简化错误处理,但在这种特殊情况下,我不需要指针。这段代码似乎可以工作,但是是多余的。如您所见,我总是要做assert_no_bad_variant_access<decltype(v), int>(v, "msg");。我可以以某种方式简化它以避免必须通过decltype(v)吗?对我来说似乎很罗嗦。

理想情况下,我想要一个模板,我只需要传递get_Tvariant_T 应该以某种方式自动确定。

Play with the code.

template <typename variant_T, typename get_T>
get_T assert_no_bad_variant_access(variant_T& v, std::string_view msg) 
  try 
    return std::get<get_T>(v);
   catch (const std::bad_variant_access& bva) 
    std::cout << msg << '\n';
    get_T t;
    return t;
  


int main() 


    std::variant<int, double, std::string> v = "hi there!";
    auto result1 = assert_no_bad_variant_access<decltype(v), std::string>(v, "std::string failed");
    auto result2 = assert_no_bad_variant_access<decltype(v), int>(v, "int failed");
    return 0;   

【问题讨论】:

我建议不要将其命名为 assert。人们不会期望一个失败的断言完全没问题。像&lt;name&gt;_or_default 这样的东西更能说明函数的实际作用,尽管日志记录使这变得复杂。 【参考方案1】:

重新排序模板参数。让variant_T排在第二位,这样就可以推导出来了

template <typename get_T, typename variant_T>
get_T assert_no_bad_variant_access(variant_T& v, std::string_view msg) 
  try 
    return std::get<get_T>(v);
   catch (const std::bad_variant_access& bva) 
    std::cout << msg << '\n';
    get_T t;
    return t;
  


int main() 


    std::variant<int, double, std::string> v = "hi there!";
    auto result1 = assert_no_bad_variant_access<std::string>(v, "std::string failed");
    auto result2 = assert_no_bad_variant_access<int>(v, "int failed");
    return 0;   

请记住,只有在 尾随 可以推导出来时,我们才能指定模板参数的一部分。

顺便说一句,您不需要使用异常来检测这种情况。 std::variant API 包括 std::holds_alternative。你可以直接检查。这将避免对常规控制流使用异常。

【讨论】:

惊人的答案!真的很喜欢这个!你能告诉我更多关于部分模板的信息吗?我根本不知道这一点!你对我能读到的关于这个主题有什么建议吗? @User12547645 - cppreference 对 en.cppreference.com/w/cpp/language/template_argument_deduction 有一个不错的概述

以上是关于调用此模板时如何避免使用 decltype?的主要内容,如果未能解决你的问题,请参考以下文章

从可变参数模板中扩展的 decltype 继承

decltype 是如何工作的?

,带你玩转 函数模板以及重载解析,函数还可以这样玩?

在django中渲染模板后如何在我的视图中调用一些逻辑

如何避免在Reactjs中每次都调用API?

如何避免两次调用observe()?