【问题标题】:Overloading templated function, with different return types based on template parameter [duplicate]重载模板函数,根据模板参数具有不同的返回类型[重复]
【发布时间】:2013-09-16 16:05:35
【问题描述】:

我有一个带参数的函数。有时它是一个“原始”数字,有时它是一个包含在包含有关数字的一些元信息的持有者类中的数字。我可以像这样区分这两种情况

template<class T>
struct Holder
{
};

template<class T>
void f1(T)
{
}

template<class T>
void f1(Holder<T>)
{
}

但是,现在我想根据用户的需要返回原始数字或持有人。我知道用户在调用函数时必须明确指定模板参数。没关系,但如果可能的话,我希望该函数具有相同的名称。像这样的

template<class T>
T f1()
{
    return T();
}

template<class T>
Holder<T> f1()
{
    return T();
}

但是,将其称为 f1&lt;int&gt;(); 或 f1&lt;Holder&lt;int&gt;&gt;(); 会导致 error: ambiguous call to overloaded function

是否可以在不更改函数名称的情况下做到这一点? (如果没有,也没什么大不了的,我只是好奇)

【问题讨论】:

  • 不,这是不可能的。您不能仅在返回类型上重载函数。
  • 不是骗子,因为我们在这里讨论的是模板。

标签: c++


【解决方案1】:

除了使用 SFINAE (std::enable_if) 的方法之外,您还可以使用部分专业化。由于函数模板无法实现部分特化,因此需要一些麻烦:

template <typename T>
struct f1_specialization {
    static T f1() { ... }
};
template <typename T>
struct f1_specialization<Holder<T>> {
    static Holder<T> f1() { ... }
};
template <typename T>
T f1() { return f1_specialization<T>::f1(); }

这两种方法可能或多或少都清楚,它们都应该有效。

【讨论】:

  • +1,我更喜欢你的解决方案。我最近写了太多enable_ifs。
【解决方案2】:

是的,可以使用enable_if。但这太可怕了。我将用 C++11 编写。

template <typename T> struct is_holder {
  static constexpr bool value = false;
};
template <typename T> struct is_holder<Holder<T>> {
  static constexpr bool value = true;
};

template <typename T,
          typename = typename std::enable_if<is_holder<T>::value>::type>
T f1() {
  // T is Holder<U>
}

template <typename T,
          typename = typename std::enable_if<!is_holder<T>::value>::type>
T f1() {
  // T is not Holder<U>
}

当然,您仍然必须在调用模板参数时显式指定它。

【讨论】:

    【解决方案3】:

    结帐decltype。

        template <class T, class U>
        auto add(T t, U u) -> decltype(t + u);
    

    【讨论】:

    • 您能解释一下这如何解决我的问题吗?
    • 也许我读错了你的问题,但我发布的代码是模板返回类型的示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多