gpt4 book ai didi

c++ - 推断 CRTP 中模板化成员函数的返回类型

转载 作者:可可西里 更新时间:2023-11-01 16:04:50 35 4
gpt4 key购买 nike

是否可以推断 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

对于函数具有一个或多个模板化参数的情况,Dietmar Kü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;
}
};

最佳答案

一个额外的间接是你的 friend :

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);
}
};

关于c++ - 推断 CRTP 中模板化成员函数的返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18392225/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com