Компиляция только в том случае, если функция поддерживает переданные подходящие аргументы variadi c - PullRequest
0 голосов
/ 04 марта 2020
#include <iostream>
#include <utility>

class A 
{
  public:
  void run(int value)
  {
      std::cout << value << std::endl;
  }
};

class B 
{
  public:
  void run(int value1, int value2)
  {
      std::cout << value1 << " "
                << value2 
                << std::endl;
  }
};


template<typename T,
          typename ... Args>
void call_run(T& t, Args&& ... args)
{
    // scope below should compile only
    // if T has a run function and 
    // this run function has a signature 
    // matching Args
    // (empty score otherwise)
    {
        t.run(std::forward<Args>(args)...);
    }

}


int main()
{

    int value = 1;

    A a;
    call_run(a,value);

    // compilation error if uncommented
    //B b;
    //call_run(b,value);

    return 0;
}

Приведенный выше код компилируется и работает нормально. Но если последняя часть, вызывающая call_run с экземпляром B, не закомментирована, код не может быть скомпилирован по очевидным причинам:

main.cpp:34:9: error: no matching function for call to ‘B::run(int&)’
     t.run(std::forward<Args>(args)...);

Возможно ли его скомпилировать, игнорируя область, которая не является применимо? (игнорирование здесь означает замену дефектной области на пустую область во время компиляции)

1 Ответ

4 голосов
/ 05 марта 2020

Начиная с c ++ 17, вы можете использовать if constexpr:

if constexpr (std::is_invocable_v<decltype(&T::run),T*,Args...>)
{
    t.run(std::forward<Args>(args)...);
}

invocable проверяется во время компиляции, и если он возвращает false, тело , если область игнорируется.

Демонстрационная версия

...