【问题标题】:How to return different types based on std::is_same check [duplicate]如何根据 std::is_same 检查返回不同类型
【发布时间】:2018-06-06 00:25:38
【问题描述】:

考虑以下代码:

template<typename T>
T foo() {
    if (std::is_same<T, int>::value)
        return 5;

    if (std::is_same<T, std::string>::value)
        return std::string("bar");

    throw std::exception();
}

使用foo&lt;int&gt;() 调用时,会抛出错误cannot convert ‘std::__cxx11::string {aka std::__cxx11::basic_string&lt;char&gt;}’ to ‘int’ in return

我知道解决方案是使用模板专业化,但我想问是否有可能通过std::is_same 检查类型来保持当前机制?

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    if 的两个分支必须在编译时有效,即使其中一个从未执行。

    如果您可以访问 C++17,请将 ifs 更改为 if constexpr

    template<typename T>
    T foo() {
        if constexpr (std::is_same<T, int>::value)
            return 5;
    
        if constexpr (std::is_same<T, std::string>::value)
            return std::string("bar");
    
        throw std::exception();
    }
    

    在 C++17 之前,您必须使用模板特化来模拟:

    template<typename T>
    T foo()
    {
        throw std::exception();
    }
    
    template <>
    int foo<int>() {
        return 5;
    }
    
    template <>
    std::string foo<std::string>() {
        return "bar";
    }
    

    如果你真正的 foo 比这个例子做更多的工作并且专门化它会导致代码重复,你可以引入一个辅助函数,它只封装 return/throw 语句,并专门化它。

    【讨论】:

      【解决方案2】:

      在 C++17 之前的编译器中,您可以使用标签调度来获得所需的内容。

      template <typename T> tag_t {};
      
      int foo(tag_t<int> t) { return 5; }
      
      std::string foo(tag_t<std::string> t) { return "bar"; }
      
      template<typename T>
      T foo() {
          return foo(tag_t<T>());
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-03-08
        • 1970-01-01
        • 1970-01-01
        • 2022-11-27
        • 1970-01-01
        • 2019-12-14
        • 1970-01-01
        相关资源
        最近更新 更多