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

c++ - How to constrain template methods to match class template parameters? - Stack Overflow

programmeradmin2浏览0评论

I have a following class:

template<typename Population, typename... Operators> class GA
{
public:
    template<typename Evaluator,
             typename std::enable_if_t<
             std::is_same_v<Evaluator, Evaluator<Operators...>>>>
  void EvaluatePopulation(Evaluator& evaluator)
  {
    evaluator.Evaluate();
  }
};

This doesn't compile, because of incorrect EvaluatePopulation declaration.

How do I specify that EvaluatePopulation method can be called only with Evaluator class that was initialized with the same Operators... as the GA class?

I have a following class:

template<typename Population, typename... Operators> class GA
{
public:
    template<typename Evaluator,
             typename std::enable_if_t<
             std::is_same_v<Evaluator, Evaluator<Operators...>>>>
  void EvaluatePopulation(Evaluator& evaluator)
  {
    evaluator.Evaluate();
  }
};

This doesn't compile, because of incorrect EvaluatePopulation declaration.

How do I specify that EvaluatePopulation method can be called only with Evaluator class that was initialized with the same Operators... as the GA class?

Share Improve this question edited Mar 30 at 20:17 JeJo 33.5k6 gold badges53 silver badges94 bronze badges asked Mar 30 at 17:21 PeterPeter 1111 silver badge8 bronze badges 1
  • Can't doublecheck the syntax right now but I think you just need a template-template parameter instead like template<template<typename...> Evaluator> void EvaluatePopulation(Evaluator<Operators...>& evaluator) – NathanOliver Commented Mar 30 at 17:26
Add a comment  | 

1 Answer 1

Reset to default 9

How do I specify that EvaluatePopulation method can be called only with Evaluator class that was initialised with the same Operators... as the GA class?

The trick is to use a template template parameter so that you “unpack” the evaluator’s template arguments to match the GA’s pack. For example, you can write:

template<typename Population, typename... Operators>
class GA
{
public:
    template<template<typename...> class EvaluatorT>
    void EvaluatePopulation(EvaluatorT<Operators...>& evaluator)
    {
        evaluator.Evaluate();
    }
};

((See live demo))


Alternatively, using c++20's concepts, which gives clearer error messages:

// Ensures Evaluator is instantiated with exactly Operators...
template<typename T, typename... Args>
constexpr bool is_evaluator_for_v = false;

template<template<typename...> class EvaluatorT, typename... Ops>
constexpr bool is_evaluator_for_v<EvaluatorT<Ops...>, Ops...> = true;

template<typename Evaluator, typename... Operators>
concept EvaluatorFor = is_evaluator_for_v<Evaluator, Operators...>;

template<typename Population, typename... Operators> class GA 
{
public:
    
    template<typename Evaluator> requires EvaluatorFor<Evaluator, Operators...>
    void EvaluatePopulation(Evaluator& evaluator) 
    {
        evaluator.Evaluate();
    }
};

((See live demo))

发布评论

评论列表(0)

  1. 暂无评论