2014-12-19 7 views
5

У меня есть функция foo(), которая предоставляется в контексте библиотеки. Библиотека определяет несколько перегрузок для этой функции, как:.Как обернуть несколько перегрузок функций с помощью общего объекта функции TR1?

char foo(float x, int y); 
short foo(double x, char y); 

(я сделал выше аргументы/тип результатов до выноса в том, что не существует общее отношение между типами аргументов и перегрузкой-х соответствующих возвращаемый тип.)

Идея состоит в том, что пользователь библиотеки может добавлять перегрузки для foo() для собственных пользовательских типов по мере необходимости. Перегрузка функций позволяет сделать это очень легко.

Я хотел бы сделать семейство функций foo(), которые можно использовать в выражении Boost.Proto. Для того, чтобы сделать это, я думаю, что я должен был бы обернуть выше в объекте функции с помощью оператора шаблона вызова:

struct foo_wrap 
{ 
    template <typename A1, typename A2> 
    result_type operator()(A1 a1, A2 a2) { return foo(a1, a2); } 
}; 

Проблема возникает с тем, как определить result_type. Я понимаю, что это было бы легко с C++ 11 и decltype() и возвращаемыми типами возвращаемых функций, но я ищу решение C++ 03. Следовательно, foo_wrap должен быть объектом функции стиля TR1. Мне нужно найти способ определить result_type как функцию времени компиляции типов аргументов A1 и A2. Это необходимо не только для возвращаемого типа operator(), но и для протокола TR1 result_of. Короче говоря:

  • Существует ли метод метапрограммирования, который при заданном имени функции и наборе типов аргументов даст соответствующий возвращаемый тип функции?
  • В качестве альтернативы, есть ли другой способ, который я могу использовать для переноса нескольких перегрузок функции с помощью общего объекта функции?
+0

Как портативный вы должны быть в условия поддержки для разных компиляторов? – cdhowie

+0

Я ищу поддержку любого разумного C++ 03-совместимого компилятора. Вероятно, минимум gcc 4.1 или около того. Я не особо обеспокоен MSVC, хотя было бы неплохо, если бы там тоже работало. –

+0

Если g ++ является вашей основной целью, вы * можете * использовать свою фирменную функцию 'typeof()' здесь. – cdhowie

ответ

4

Вы можете кормить вручную черты для этого:

template <typename A1, typename A2> 
struct foo_wrap_result; 

с

struct foo_wrap 
{ 
    template <typename A1, typename A2> 
    typename foo_wrap_result<A1, A2>::type 
    operator()(A1 a1, A2 a2) const { return foo(a1, a2); } 
}; 

и специализации черт:

template <> 
struct foo_wrap_result<float, int> { typedef char type; }; 

template <> 
struct foo_wrap_result<double, char> { typedef short type; };