最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Use template functions inside template - Stack Overflow

programmeradmin0浏览0评论

I want to implement the following for more than one (i.e. many) functions (function1(), function2(), ...etc.).

Currently I have it separately as follows:

template <typename T>
concept iterator_1 = requires(T const& t) {
  t.function1();
};
template <iterator_1 R>
static float getterFunction(R const& r)
{
  return r.function1();
}
template <typename T>
concept iterator_2 = requires(T const& t) {
  t.function2();
};
template <iterator_2 R>
static float getterFunction(R const& r)
{
  return r.function2();
}

I want to use a general getterFunction to choose function1(), function2(), ...etc. with an if condition, such as follows:

template <typename A>
float getterFunction(A const& a)
{
  auto i = -1;
  if (something==0) {
    i = a.function1();
  } 
  else if (something==1) {
    i = a.function2();
  }
  else if {
    ...
  }
  return i;
}

I would like to use this general getterFunction as follows:

template <typename B> 
void DoSomething(typename B::iterator const& b)
{
  float value = getterFunction(b);
  ...
}

I was wondering if there is a more general way of doing this, instead of writing many concepts for each of the many functions?

I want to implement the following for more than one (i.e. many) functions (function1(), function2(), ...etc.).

Currently I have it separately as follows:

template <typename T>
concept iterator_1 = requires(T const& t) {
  t.function1();
};
template <iterator_1 R>
static float getterFunction(R const& r)
{
  return r.function1();
}
template <typename T>
concept iterator_2 = requires(T const& t) {
  t.function2();
};
template <iterator_2 R>
static float getterFunction(R const& r)
{
  return r.function2();
}

I want to use a general getterFunction to choose function1(), function2(), ...etc. with an if condition, such as follows:

template <typename A>
float getterFunction(A const& a)
{
  auto i = -1;
  if (something==0) {
    i = a.function1();
  } 
  else if (something==1) {
    i = a.function2();
  }
  else if {
    ...
  }
  return i;
}

I would like to use this general getterFunction as follows:

template <typename B> 
void DoSomething(typename B::iterator const& b)
{
  float value = getterFunction(b);
  ...
}

I was wondering if there is a more general way of doing this, instead of writing many concepts for each of the many functions?

Share Improve this question edited Feb 3 at 10:07 Gyulaxxx asked Feb 1 at 18:18 GyulaxxxGyulaxxx 112 bronze badges 1
  • Side note: code like your general getterFunction that calls a specific function according to a bunch of if statements is not a good sign in terms of design. Unless you absolutely want to use templates, you could as well define some interface class declaring function as virtual and then defines classes that implement this interface. As a consequence getterFunction becomes trivial and you can add other implementations without having to change getterFunction itself. – edrezen Commented Feb 3 at 11:05
Add a comment  | 

1 Answer 1

Reset to default 1

Since concepts are checked at compile time, you could use if constexpr which discards any non-taken branch:

template <typename A>
auto getterFunction(A const& a)
{
    if constexpr (iterator_1<A>) {
        return a.function1();
    } else if constexpr (iterator_2<A>) {
        return a.function2();
    } else {
        static_assert(false);
    } 
}

}

You may want to consider adding a check that only one concept is satisfied, as any type which satisfies more will just use the first one in the checked order. static_assert(std::ranges::count({ iterator_1<A>, iterator_2<A>... }, true) == 1); should do the trick.

发布评论

评论列表(0)

  1. 暂无评论