是否有一种干净的方法将模板参数转发到模板函数?

发布于 2025-02-13 06:15:56 字数 1624 浏览 0 评论 0 原文

但是,以下作用是

#include <iostream>

template<typename A, typename B> double func1(B x, B y) 
{
    A a = 3.0f;
    return a + x + y;
}

template<typename A, typename B> double func2() 
{
    B x = 5.0;
    B y = 8.0;
    return func1<float>(x, y);
}

int main() 
{
    std::cout << func2<float, double>() << "\n";
}

,如果我想用另一个类似功能替换 func1 该怎么办?一个具有相同数字和类型的参数和模板参数。我尝试了模板&lt; template&lt; ... 如下所示,但似乎没有用。

#include <iostream>

template<typename A, typename B> double func1(B x, B y) 
{
    A a = 3.0f;
    return a + x + y;
}

template<template <typename, typename> typename func, class A, class B>
double func2() 
{
    B x = 5.0;
    B y = 8.0;
    return func<A, B>(x, y);
}

int main()
{
    std::cout << func2<func1, float, double>() << "\n";
}

如果上面的模式有效,那就太好了。


如果 func 可以部分地进行模板,并且仍然从参数的类型中推断出更好的说法,例如

#include <iostream>

template<typename A, typename B> double func1(B x, B y)
{
    A a = 3.0f;
    return a + x + y;
}

template<template <typename, typename> typename func, class A, class B>
double func2()
{
    B x = 5.0;
    B y = 8.0;
    return func<A>(x, y);
}

int main() 
{
    std::cout << func2<func1, float, double>() << "\n";
}

关于如何使第二片片段工作的任何想法,更好的是更好?

您还可以通过模板扣除来做到这一点吗? C ++ 20个概念可以在这里做魔术吗?

The following works

#include <iostream>

template<typename A, typename B> double func1(B x, B y) 
{
    A a = 3.0f;
    return a + x + y;
}

template<typename A, typename B> double func2() 
{
    B x = 5.0;
    B y = 8.0;
    return func1<float>(x, y);
}

int main() 
{
    std::cout << func2<float, double>() << "\n";
}

However, what if I would like func1 to be substituted with another similar function? One with the same number and type of arguments and template parameters. I tried template<template<... like below, and it didn't seem to work.

#include <iostream>

template<typename A, typename B> double func1(B x, B y) 
{
    A a = 3.0f;
    return a + x + y;
}

template<template <typename, typename> typename func, class A, class B>
double func2() 
{
    B x = 5.0;
    B y = 8.0;
    return func<A, B>(x, y);
}

int main()
{
    std::cout << func2<func1, float, double>() << "\n";
}

It would be nice if a pattern like the one above worked.


Even better if func, could be partially templatized and still deduce from the type of the arguments like

#include <iostream>

template<typename A, typename B> double func1(B x, B y)
{
    A a = 3.0f;
    return a + x + y;
}

template<template <typename, typename> typename func, class A, class B>
double func2()
{
    B x = 5.0;
    B y = 8.0;
    return func<A>(x, y);
}

int main() 
{
    std::cout << func2<func1, float, double>() << "\n";
}

Any ideas on how to get the 2nd snippet to work?

Could you do so with template deduction as well? Could c++20 concepts do magic here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情话墙 2025-02-20 06:15:56

功能模板具有一些类模板没有的限制。考虑 func1&lt; a,b&gt; 的类型对您无济于事。您需要调用具体功能。另一方面,使用类模板,您需要知道的所有类型(模板的实例化)就是使用它。

如果您仅更改 func1 为函数,则可以使用 operator()

#include <iostream>

template<typename A, typename B>
struct func1  {
    double operator()(B x, B y){
      A a = 3.0f;
      return a + x+ y;
    } 
};

template<template <typename, typename> typename func, class A, class B>
double func2(){
  B x = 5.0;
  B y = 8.0;
  return func<A,B>{}(x,y);
}

int main(){
  std::cout << func2<func1, float,double>() << "\n";
}

从参数中推论 b ,则 可以使用第二个代码段。可以使 operator()模板:

#include <iostream>


template <typename A>
struct func1  {
template<typename B>
double operator()(B x, B y){
  A a = 3.0f;
  return a + x+ y;
} 
};

template<template <typename> typename func, class A, class B>
double func2(){
  B x = 5.0;
  B y = 8.0;
  return func<A>{}(x,y);
}

int main(){
  std::cout << func2<func1, float,double>() << "\n";
}

Function templates have some restrictions that class templates do not have. Consider that the type of func1<A,B> alone does not help you. You'd need the concrete function to call it. With a class template on the other hand, the type (an instantiation of the template) is all you need to know to use it.

Your 2nd code snippet works if you only change func1 to be a functor, a class with operator():

#include <iostream>

template<typename A, typename B>
struct func1  {
    double operator()(B x, B y){
      A a = 3.0f;
      return a + x+ y;
    } 
};

template<template <typename, typename> typename func, class A, class B>
double func2(){
  B x = 5.0;
  B y = 8.0;
  return func<A,B>{}(x,y);
}

int main(){
  std::cout << func2<func1, float,double>() << "\n";
}

To deduce B from the parameters you can make operator() a template:

#include <iostream>


template <typename A>
struct func1  {
template<typename B>
double operator()(B x, B y){
  A a = 3.0f;
  return a + x+ y;
} 
};

template<template <typename> typename func, class A, class B>
double func2(){
  B x = 5.0;
  B y = 8.0;
  return func<A>{}(x,y);
}

int main(){
  std::cout << func2<func1, float,double>() << "\n";
}
油饼 2025-02-20 06:15:56

替代其他答案中给出的模板函数,也可以使用通用lambda,以及 lambda的模板支持来自 c ++ 20

// generic lambda
const auto func1 = [](auto x,auto y)
{
    decltype(x) a = 3.0f;
    return static_cast<double>(a + x + y);
};

template<typename Func, class A, class B>
double func2() {
    B x = 5.0;
    B y = 8.0;
    return Func{}.template operator()<A> (x, y);
    //          ^^^^^^^^^^^^^^^^^call of lambda like templated lambda!
}

这需要打电话为:

std::cout << func2<decltype(func1), float, double>() << "\n";
           // ^^^^^^^^^^^^^^^^^^^passing type of the lambda

请参阅实时演示

Alternative to the templated functors given in the other answers, one can also use a generic lambda, along with the lambda's template support from .

// generic lambda
const auto func1 = [](auto x,auto y)
{
    decltype(x) a = 3.0f;
    return static_cast<double>(a + x + y);
};

template<typename Func, class A, class B>
double func2() {
    B x = 5.0;
    B y = 8.0;
    return Func{}.template operator()<A> (x, y);
    //          ^^^^^^^^^^^^^^^^^call of lambda like templated lambda!
}

This required the calling to be like:

std::cout << func2<decltype(func1), float, double>() << "\n";
           // ^^^^^^^^^^^^^^^^^^^passing type of the lambda

See live demo

雪若未夕 2025-02-20 06:15:56

如果弹药可以部分地进行模板,但仍然可以推断出来

等参数的类型中

您可以将 func1 转换为带有模板 operator()的函数,而部分 通过<指定模板参数代码> .template operator()&lt; a&gt; 。

#include <iostream>

struct Fun1 {
  template<typename A, typename B>
  double operator()(B x, B y){
    A a = 3.0f;
    return a + x + y;
  }
};

template<typename Func, class A, class B>
double func2(){
  B x = 5.0;
  B y = 8.0;
  return Func{}.template operator()<A>(x, y);
}

int main(){
  std::cout << func2<Fun1, float, double>() << "\n";
}

Even better if func, could be partially templatized and still deduce
from the type of the arguments like

You can turn func1 into an functor with a template operator(), and partially specify the template parameter through .template operator()<A>.

#include <iostream>

struct Fun1 {
  template<typename A, typename B>
  double operator()(B x, B y){
    A a = 3.0f;
    return a + x + y;
  }
};

template<typename Func, class A, class B>
double func2(){
  B x = 5.0;
  B y = 8.0;
  return Func{}.template operator()<A>(x, y);
}

int main(){
  std::cout << func2<Fun1, float, double>() << "\n";
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文