簡體   English   中英

在CRTP中推斷返回類型的模板化成員函數

[英]Inferring return type of templated member functions in CRTP

是否可以推斷CRTP基類中模板化成員函數的返回類型?

推斷參數類型效果很好,但它返回類型失敗。 考慮下面的例子。

#include <iostream>

template <typename Derived>
struct base
{
  template <typename R, typename T>
  R f(T x)
  {
    return static_cast<Derived&>(*this).f_impl(x);
  }
};

struct derived : base<derived>
{
  bool f_impl(int x)
  {
    std::cout << "f(" << x << ")" << std::endl;
    return true;
  }
};

int main()
{
  bool b = derived{}.f(42);
  return b ? 0 : 1;
}

這會產生以下錯誤:

  bool b = derived{}.f(42);
           ~~~~~~~~~~^
crtp.cc:7:5: note: candidate template ignored: couldn't infer template argument 'R'
  R f(T x)
    ^
1 error generated.

我的直觀假設是,如果編譯器能夠為f的參數推斷類型int ,它也應該適用於返回bool ,因為這兩種類型在模板實例化時都是已知的。

我嘗試使用尾隨返回類型函數語法,但后來找不到要放入decltype的工作表達式。

編輯1

對於函數具有一個或多個模板化參數的情況,DietmarKühl提供了一種基於使用間接層延遲模板實例化的解決方案。 不幸的是,當基類函數沒有任何參數時,這不起作用,如下所示:

template <typename R>
R g()
{
  return static_cast<Derived&>(*this).g_impl();
}

嘗試使用相同的技術失敗,因為不存在依賴類型。 如何處理這種情況?

編輯2

正如Johannes Schaub所指出的,C ++ 11具有默認模板參數,因此始終可以使g依賴於任意類型,然后應用Dietmar的解決方案:

template <typename T = void>
auto g() -> typename g_impl_result<Derived, T>::type
{
  return static_cast<Derived&>(*this).g_impl();
}

編輯3

這個問題在C ++ 14中不再存在,因為我們對正常函數有返回類型推導,允許我們簡單地寫:

template <typename Derived>
struct base
{
  template <typename T>
  auto f(T x)
  {
    return static_cast<Derived&>(*this).f_impl(x);
  }

  auto g()
  {
    return static_cast<Derived&>(*this).g_impl();
  }
};

struct derived : base<derived>
{
  bool f_impl(int x)
  {
    return true;
  }

  double g_impl()
  {
    return 4.2;
  }
};

額外的間接是你的朋友:

template <typename D, typename T>
struct f_impl_result
{
    typedef decltype(static_cast<D*>(0)->f_impl(std::declval<T>())) type;
};

template <typename Derived>
struct base
{
    template <typename T>
    auto f(T x) -> typename f_impl_result<Derived, T>::type
    {
        return static_cast<Derived&>(*this).f_impl(x);
    }
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM