Как определить тип возвращаемого значения функции во время создания шаблона? - PullRequest
2 голосов
/ 21 июня 2011

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

У меня есть следующий код, который ломается, когда я использую функцию voidуказатель, но отлично работает для любого другого типа возврата.Ошибка, которую я получаю при использовании указателя на функцию void из gcc 4.5:

error: значение void не игнорируется, так как оно должно быть

Что имеет смысл.Поэтому, очевидно, мне нужно проверить, возвращает ли указатель на функцию что-то, а затем получить результат и вернуть его.

template <class F,typename R> class Instruction
{
  protected:
    F (func);
    R result;

  public:

   template <typename T>
   Instruction(T const& f)
   {
     func = &f;
   };

   template <typename A> void execute(A const& a)
   {
     result = (func)(a);
   };
   template <typename A> void execute(A const& a,A const& b)
   {
     result = (func)(a,b);
   };
   template <typename A> void execute(A const& a,A const& b,A const& c)
   {
     result = (func)(a,b,c);
   };
   R get_result()
   {
     return result;
   }; 
};

Обычно я использую указатель на функцию, которая выполняет что-то в основном арифметическое, и я могу позаботиться олюбой тип возвращаемого значения в экземпляре, кроме функций void.Я попытался создать экземпляр как:

     Instruction<ptr2func2,void> foo(bar);
     Instruction<ptr2func2,(*void)> foo(bar);

, но в обоих случаях это не удалось.

Второй аргумент шаблона при создании экземпляра используется для определения типа возвращаемого значения.

Ответы [ 3 ]

3 голосов
/ 21 июня 2011

Попробуйте шаблон частичной специализации на void:

template <class F> class Instruction<F, void>
{
  protected:
    F (func);

  public:

   template <typename T>
   Instruction(T const& f)
   {
     func = &f;
   };

   template <typename A> void execute(A const& a)
   {
     (func)(a);
   };
   template <typename A> void execute(A const& a,A const& b)
   {
     (func)(a,b);
   };
   template <typename A> void execute(A const& a,A const& b,A const& c)
   {
     (func)(a,b,c);
   };
};
1 голос
/ 21 июня 2011

В C ++ 0x вы можете decltype. Однако в C ++ 03, по соглашению, функциональные объекты имеют result_type typedef, и к указателям на функцию может быть применен шаблонный вывод.

1 голос
/ 21 июня 2011

Возможно, вы захотите использовать Boost :: FunctionTypes , которые предоставляют метафункцию, способную разложить тип функции и дают вам доступ к типу возвращаемого значения или аргумента.

...