++ 11:
#include <type_traits>
#include <iostream>
template <typename Param, typename Arg>
Param take_address_if_necessary_impl (Arg&& arg, std::true_type, std::false_type)
{
return arg;
}
template <typename Param, typename Arg>
Param take_address_if_necessary_impl (Arg&& arg, std::false_type, std::true_type)
{
return &arg;
}
template <typename Param, typename Arg>
Param take_address_if_necessary (Arg&& arg)
{
return take_address_if_necessary_impl <Param> (
arg,
typename std::is_convertible <Arg, Param>::type {},
typename std::is_convertible <typename std::add_pointer <Arg>::type, Param>::type {}
);
}
template <typename Ret, typename... Params, typename... Args>
Ret call_special (Ret (*f) (Params...), Args&&... args)
{
return f (take_address_if_necessary <Params, Args> (args)...);
}
template <typename... Params, typename... Args>
void call_special (void (*f) (Params...), Args&&... args)
{
f (take_address_if_necessary <Params> (args)...);
}
void function (int* i, char* c)
{
std::cout << *i << ' ' << *c << std::endl;
}
int main ()
{
int i = 42;
char c = '%';
call_special (function, 1, 'f');
call_special (function, &i, '?');
call_special (function, &i, &c);
}
1 f
42 ?
42 %
.
: -, , , ++ :
void bar (int);
void bar (float);
call_special (bar, 3.0f);
, :
call_special <float> (bar, 3.0f);
, , :
call_special ((void (*) (float))bar, 3.0f);
-, call_special . , , r, const ..
-, , , , . , , , :
void quux (long* i)
{
if (i)
std::cout << *i << std::endl;
else
std::cout << "(null)" << std::endl;
}
call_special (quux, NULL);
:
template <typename T>
T* foo (T&& t)
{
return &t;
}
function (foo (3), foo ('7'));
, , , , . , , , , , , .