I am using C++03. Thus I don't have std::bind(). My compiler is ported from g++, but tr1::bind() is not ported.
I want to bind a function having 3 arguments. Thus std::bind1st() and std::bind2nd() won't work. In addition, neither std::bind1st() or std::bind2nd() deal with reference type of argument.
Thus I am writing my own version of bind1st() as follows, including sample invocation of my bind1st():
#include <iostream>
// c++03 does not define nullptr
#ifndef nullptr
#define nullptr ((void*)0)
#endif
namespace mybinder {
void *binder3ArgToBind;
void *binder3FunctorToCall;
template <int uniqueID, typename USER_FUNC_TYPE, typename BOUND_FUNC_TYPE,
typename returnType, typename T1, typename T2, typename T3>
class binder3 // 3 arguments binder
{
public:
static void setParams(void **pArg1, void **pFunc) {
*pArg1 = binder3ArgToBind;
*pFunc = binder3FunctorToCall;
binder3ArgToBind = nullptr;
}
static returnType f_bound1st_common(T2 &arg2, T3 &arg3) {
static void *arg1;
static void *func;
returnType ignored;
if (binder3ArgToBind != nullptr) {
setParams(&arg1, &func);
return ignored;
}
return ((USER_FUNC_TYPE)func)(*(T1*)arg1, arg2, arg3);
}
static returnType f_bound1st(T2 arg2, T3 arg3) {
return f_bound1st_common(arg2, arg3);
}
static returnType f_bound1st(T2 &arg2, T3 arg3) {
return f_bound1st_common(arg2, arg3);
}
static returnType f_bound1st(T2 arg2, T3 &arg3) {
return f_bound1st_common(arg2, arg3);
}
static returnType f_bound1st(T2 &arg2, T3 &arg3) {
return f_bound1st_common(arg2, arg3);
}
static BOUND_FUNC_TYPE bind1st(USER_FUNC_TYPE f, T1 &arg1) {
binder3FunctorToCall = (void*)f;
binder3ArgToBind = (void*) &arg1;
(*(void (*)())f_bound1st_common)();
return f_bound1st;
}
};
}
using namespace std;
using namespace mybinder;
typedef short (*FUNC)(int const, int&);
// test function
short f(int &a, int const b, int &c)
{
int val = 100 * a + 10 * b + c;
a+=100;
c+=10;
return val;
}
int main(void)
{
int a[2] = {2, 5};
for (int i=0; i<2; ++i) {
// bind function f with a[i] as its 1st argument.
FUNC ff = binder3<__COUNTER__, short(*)(int&, int const, int&), short(*)(int const,int&), short, int, int const, int>::bind1st(f, a[i]);
int k;
int m;
for (m=0; m<2; ++m) {
k = 1-m;
cout << "before: a[i]=" << a[i] << endl;
cout << "before: m=" << m << endl;
cout << "before: k=" << k << endl;
cout << ff(m, k) << endl;
cout << "after: a[i]=" << a[i] << endl;
cout << "after: m=" << m << endl;
cout << "after: k=" << k << endl << endl;
}
}
}
And the execution results:
before: a[i]=2
before: m=0
before: k=1
201
after: a[i]=102
after: m=0
after: k=11
before: a[i]=102
before: m=1
before: k=0
10210
after: a[i]=202
after: m=1
after: k=10
before: a[i]=5
before: m=0
before: k=1
501
after: a[i]=105
after: m=0
after: k=11
before: a[i]=105
before: m=1
before: k=0
10510
after: a[i]=205
after: m=1
after: k=10
It works fine on my PC, as an emulation. However, it raises several problems in my embedded compiler:
(1) The embedded compiler does not support __COUNTER__
(2) The invoke of bind1st() is tedious, and those redundant types in the template may get problem, if they are not synchronized.
Thus my question:
(1) How do I implement __COUNTER__ as in regular g++/gcc? Or, In fact, I only need a unique number/identifier than a counter.
(2) Is there anyway I can derive argument types and return types from the function pointer type?
(3) Even if Question (2) can be done, can I derive bare types from a reference type? For example, can I derive int from int &? Please note that the source type can be int or int &, and I need to derive the resulting type int in both cases. Please note that it's C++03, not C++11 or higher.
(4) Any other suggestions? Perhaps someone can provide a simpler or better implementation?
The goal of Q.2 and Q.3 is to make template call shorter, like FUNC ff = binder3<__COUNTER__, short(*)(int&, int const, int&)>::bind1st(f, a[i]);. All other types can be derived from the first function pointer type. In addition, I don't have to write 4 overloads.
---UPDATE---
Since the implementation uses pointers to get the binding argument and the function, it may have a potential bug/design flaw:
If the caller changes the value of the binding variable after it calls binder3<...>::bind1st(), but before the use(call) of the bound function, the effective value is the value AFTER change, not BEFORE change!
Currently I can live with it, by careful coding. And normally I use(call) the bound function right after the bind1st() (without any command in-between).
Ideas to improve this problem are welcome.
--UPDATE--
Currently, use of __COUNT__ contains a bug: Since __COUNT__ is not globally unique (restart count from zero for each compilation of .cpp file), the bounding variable may be overwritten, if they are not used promptly. If I can get a program-wide global unique number to replace __COUNT__, the above implementation should be good enough (except for those tedious stuff).
Related
I wanted to write my own code to iterate over an n dimensional vector (where the dimension is known). Here is the code:
void printing(const auto& i, const int dimension){
int k= dimension;
for(const auto& j: i){
if(k>1){
cout<<"k: "<<k<<endl;
printing(j, --k);
}
else{
//start printing
cout<<setw(3);
cout<<j; //not quite sure about this line
}
cout<<'\n';
}
}
I get an error:
main.cpp:21:5: error: ‘begin’ was not declared in this scope
for(const auto& j: i){
^~~
Could someone help me to correct it or give me a better way to print the vector?
Thanks in advance for your time.
If the dimensions are known at compile-time, this can be solved easily with a template that takes dimensions as the non-type argument.
template <std::size_t Dimensions>
void printing(const auto& i){
if constexpr (Dimensions != 0) {
for(const auto& j: i){
// I'm not sure if it is intentional to print 'k' each iteration,
// but this is kept for consistency with the question
cout<<"k: " << Dimensions << endl;
printing<Dimensions - 1u>(j);
}
} else {
cout << setw(3);
cout << j;
cout << '\n';
}
}
The use would be, for a 2d vector:
printing<2>(vec);
Live Example
However, if you always know that const auto& i will be a std::vector type, you can potentially solve this even easier by just not using auto arguments at all, and instead use template matching:
// called only for the vector values
template <typename T>
void printing(const std::vector<T>& i){
for(const auto& j: i){
// possibly compute 'k' to print -- see below
printing(j);
}
}
// Only called for non-vector values
template <typename T>
void printing(const T& v) {
cout << setw(3);
cout << v;
cout << '\n';
}
Live Example
To compute the "dimension" of the vector, you can write a recursive type-trait for that:
#include <type_traits> // std::integral_constant
// Base case: return the count
template <std::size_t Count, typename T>
struct vector_dimension_impl
: std::integral_constant<std::size_t, Count> {};
// Recursive case: add 1 to the count, and check inner type
template <std::size_t Count, typename T, typename Allocator>
struct vector_dimension_impl<Count, std::vector<T,Allocator>>
: vector_dimension_impl<Count + 1u, T> {};
// Dispatcher
template <typename T>
struct vector_dimension : vector_dimension_impl<0u, T> {};
// Convenience access
template <typename T>
inline constexpr auto vector_dimension_v = vector_dimension<T>::value;
// Simple tests:
static_assert(vector_dimension_v<std::vector<int>> == 1u);
static_assert(vector_dimension_v<std::vector<std::vector<int>>> == 2u);
static_assert(vector_dimension_v<std::vector<std::vector<std::vector<int>>>> == 3u);
Live Example
With the above recursive trait, you can get the "dimension" of each templated vector type, without requiring the user to pass in the value at all.
If you still wanted to print k: each time, you can use the above simply with:
cout << "k: " << vector_dimension_v<T> << endl;
This only works if the type is known to be a vector -- but it could be written using concepts to work with anything following the abstract definition of something like a vector as well.
If you want this to work with any range-like type, then you could replace the vector-overload with a requires(std::ranges::range<T>) instead, and change the template-specializations for finding the dimension to also use the same. I won't pollute the answer with all this code since it's largely the same as above -- but I'll link to it in action below:
Live Example
I have made a function that can print any n-dimensional iterable container:
template<typename Object, typename Iterable>
void Print(
const Iterable& iterable,
const string& separatorDimensions = "\n",
const function<void(const Object&)>& funcPrintElem = [] (const Object& obj) {
static_assert(
is_arithmetic_v<Object> || is_same_v<remove_const_t<remove_pointer_t<Object>>, char>,
R"(The object from the innermost range is not a built-in/c-string type, please provide a valid print element function.)"
);
cout << obj << ' ';
}
) {
if constexpr (ranges::range<Iterable>) {
ranges::for_each(iterable, [&] (const auto& it) { Print(it, separatorDimensions, funcPrintElem); });
cout << separatorDimensions;
} else {
funcPrintElem(iterable);
}
}
The function has a default std::function that can print any built-in type like int, unsigned char, long long etc... and the c-string like char* or const char*, if you have another object like a pair or tuple or an object of your class you can pass a function that prints your object.
You can use the function like this: (you must explicitly tell the function your inner most object like below)
int main() {
cout << "v: " << endl;
vector<uint16_t> v { 1, 2, 3 };
Print<uint16_t>(v);
cout << endl << "ll: " << endl;
list<list<const char*>> ll { { "a", "b" }, { "c", "d" } };
Print<const char*>(ll);
struct smth {
int a;
char b;
};
cout << endl << "smths: " << endl;
vector<smth> smths { { 14, '0' }, { 18, '1' } };
Print<smth>(smths, "\n", [] (const smth& obj) { cout << "a = " << obj.a << ", b = " << obj.b << endl; });
return 0;
}
The function can be found here, maybe I will update in the future to support more things.
Edit: You need to have at least c++20 for this function to work
So I have a variadic template class that has a method in which arguments for the template are captured in a lambda. Later that lambda is called. Problem is, ints that are either at the front or the back of the pack lose their value.
Here is a simplified example:
#include <iostream>
#include <functional>
void doPrint() {}
template <typename Arg, typename... Args>
void doPrint(Arg arg, Args... args) {
std::cout << arg << std::endl;
doPrint(std::forward<Args>(args)...);
}
template <typename... Args>
void print(Args... args) {
doPrint(std::forward<Args>(args)...);
}
class IntWrapper {
public:
IntWrapper(int val) : val(val) {}
int val;
};
std::ostream& operator<<(std::ostream& out, const IntWrapper& value) {
out << value.val;
return out;
}
template <typename... Args>
class TestClass {
public:
void createWrapper(Args... args) {
wrapper = [&]() -> void {
print(std::forward<Args>(args)...);
};
}
std::function<void()> wrapper;
};
int main(int argc, char *argv[])
{
std::string string = "abc";
std::cout << "Test 1:" << std::endl;
TestClass<int, const IntWrapper&, int> test1;
test1.createWrapper(1, IntWrapper(2), 3);
test1.wrapper();
std::cout << std::endl << "Test 2:" << std::endl;
TestClass<int, const IntWrapper&> test2;
test2.createWrapper(1, IntWrapper(2));
test2.wrapper();
std::cout << std::endl << "Test 3:" << std::endl;
TestClass<const IntWrapper&, int> test3;
test3.createWrapper(IntWrapper(1), 2);
test3.wrapper();
std::cout << std::endl << "Test 4:" << std::endl;
TestClass<const IntWrapper&, int, const IntWrapper&> test4;
test4.createWrapper(IntWrapper(1), 2, IntWrapper(3));
test4.wrapper();
}
This is the output I get:
Test 1:
1
2
3
Test 2:
32764
2
Test 3:
1
32764
Test 4:
1
0
3
As you can see, the wrapped ints always keep their values, but the ints sometimes don't.
I know it works if I capture by copy and don't use forward, but I can't do that in my actual use case.
So, why doesn't this work? And is there any way to fix it?
EDIT: Okay, well, so obviously I was being stupid by letting the variables go out of scope in the example. It works with local variables. However, the problem still occurs in my use case, where the variables aren't out of scope. I'll try to transfer the problem to my example and try again.
So what's happening is that your references are going out of scope before you use them.
test1.createWrapper(1, IntWrapper(2), 3);
all of those variables you passed go out of scope by the time you get to
test1.wrapper();
if you stored them locally then called, something like
int x = 1, z = 3;
IntWrapper y(2);
test1.createWrapper(x, y, z);
test1.wrapper();
it should work. For your actual code you need to either make sure that
the values are still valid from when you call createWrapper to whenever you call wrapper, or you'll need to capture by value in createWrapper.
Edit:
I missed this:
TestClass<int, const IntWrapper&, int> test1;
for test1 you aren't forwarding the int's passed in (x and z in my example above) you're forwarding the copy of x and z because those int's are being passed by value. If you change to
TestClass<int&, const IntWrapper&, int&> test1;
then I think it would work.
Minimal working example:
#include <tuple>
struct example
{
example(int, char) {}
};
int main()
{
std::tuple<example, int, double>
my_tuple(example(0, 'x'), 42, .0);
// std::tuple t = make_my_tuple(0, 'x');
return 0;
}
This works.
Is there a more elegant way to initialize only the first member, like I sketched in the comment? One which only takes the arguments to construct the first tuple member and does not initialize the others?
The reason I ask? I am just interested in the semantics of the language.
You say that giving values for the other two members is not necessary - are you worried about performance? Or that there may be no suitable value for these members?
If it's the latter, you could have your tuple hold boost::optionals. e.g.
#include <tuple>
#include <boost/optional.hpp>
using namespace boost;
struct example
{
example(int, char) {}
};
typedef std::tuple<example, optional<int>, optional<double>> MyTuple;
int main()
{
MyTuple my_tuple(example(0, 'x'), optional<int>(), optional<double>());
return 0;
}
You now semantically have the int and float "uninitialised", and can query their value as such.
To make this more elegant, you can wrap this into a function, using the perfect forwarding idiom for the arguments (in general; in this case your arguments are cheap to copy, so no speed benefit from doing this):
template <class... Args>
MyTuple make_mytuple(Args&&... args)
{
return MyTuple(example(std::forward<Args>(args)...), optional<int>(), optional<double));
}
The advantage of this template is that it's resilient to changes in example's constructor. If you add another argument, just call make_mytuple with the new arguments and it will work.
Your other point about the copying in the tuple construction is valid, but in reality I believe this will be optimal on most compilers. (a combination of RVO and elision of copies when passing an rvalue to a function by value).
You can use uniform initialization. Sadly, you cannot define a default value, argument will be initialized with the default constructor or 0.
#include <iostream>
#include <tuple>
enum class Result {Full, Partial, Empty};
std::tuple<bool, int, double> get_tuple(Result type)
{
if (type == Result::Full)
return {true, 42, 3.14159};
else if (type == Result::Partial)
return {true, 42, {}};
else
return {};
}
int main()
{
bool b;
int i;
double d;
std::tie(b, i, d) = get_tuple(Result::Full);
std::cout << b << " " << i << " " << d << std::endl;
std::tie(b, i, d) = get_tuple(Result::Partial);
std::cout << b << " " << i << " " << d << std::endl;
std::tie(b, i, d) = get_tuple(Result::Empty);
std::cout << b << " " << i << " " << d << std::endl;
return 0;
}
output:
1 42 3.14159
1 42 0
0 0 0
#include <iostream>
using namespace std;
class SampleClass
{
public:
int test(int ... arguments)
{
cout << arguments[0] << endl; // Access first element in array
return sizeof(arguments);
}
};
int main()
{
SampleClass lol;
cout << lol.test(3, 1, 4, 2, 5, 0) << endl;
return 0;
}
The test function fails due to my limited understanding in C++ semantics. But how can I fix it so that it can access the FIRST element in the arguments lits and then return the size of arguments?
As #Nik pointed out, I could obviously pass in an array, but there is no real fun with that! I am trying to do this just for learning - to see if this is even possible in C++.
Since we're all guessing at what you want, I'll throw in:
template <typename ... Ts>
size_t test(Ts ... arguments) {
auto unused = { 0, ((cout << '[' << arguments << "]\n"), 0)...};
(void)unused;
return sizeof...(arguments);
}
which works with different types of arguments (Live at Coliru). This solution is a bit too "clever" to be readable, though.
The trick here is to build a braced-initializer-list - the {...} stuff - whose elements are initialized by processing the variadic arguments in order. You then convince the compiler that said initializer list isn't used for anything, so the code will be optimized to just generate the desired side effects.
The comma operator in C++ evaluates to the value of the rightmost subexpression. The other subexpressions are evaluated and their values discarded. So ((cout << '[' << arguments << "]\n"), 0) has the effect of dumping some stuff to cout - including one of the variadic parameters - and evaluates to 0. After expanding the pack with the ... that line of code is effectively:
auto unused = { 0, ((cout << '[' << arg0 << "]\n"), 0),
((cout << '[' << arg1 << "]\n"), 0),
((cout << '[' << arg2 << "]\n"), 0) };
The cout junk is evaluated for its side effects and discarded, the whole thing is deduced as a std::initializer_list<int> just as if we had written
auto unused = { 0, 0, 0, 0 };
(The extra zero is there at the beginning to avoid a syntax error if someone calls the function with no arguments at all.)
The (void)unused; line is casting unused to void. It will compile to absolutely nothing, but also will typically tell compilers not to warn us about unused being an unused variable.
try something like this
double test( int num, ... )
{
va_list arguments; // A place to store the list of arguments
double sum = 0;
va_start ( arguments, num ); // Initializing arguments to store all values after num
for ( int x = 0; x < num; x++ ) // Loop until all numbers are added
sum += va_arg ( arguments, double ); // Adds the next value in argument list to sum.
va_end ( arguments ); // Cleans up the list
return sum / num; // Returns the average
}
so youre points are on the wrong side of your parameter list.
i hope this helps and goodluck.
Hm. You are trying to mix two features of C++, variadic-templates and variable-length argument list.
Your code will not compile at all, since you have no templates here and for variable-length argument list declaration should be
int test(int arguments...)
and you can access values from this list with functions from cstdarg header.
With variadic-templates you can do following thing
class Derived
{
public:
template<int... arguments>
int test()
{
int array[] = {arguments...};
return sizeof(array) / sizeof(*array);
}
};
use it like
cout << lol.test<3, 1, 4, 2, 5, 0>() << endl;
I am not quite sure I fully understand your question. If you want access to "the first" argument to the function rather than the template, I think something like this will do it for you, but I may be completely misunderstanding your purpose here:
#include <iostream>
template<typename... Args>
int foo(int arg0, Args... args);
template<>
int foo(int arg0)
{
// here just to catch expansion
std::cout << '[' << arg0 << ']' << std::endl;
return 1;
}
template<typename... Args>
int foo(int arg0, Args... args)
{
foo(arg0);
foo(args...);
return 1 + sizeof...(args);
}
int main()
{
std::cout << foo(1,2,3,4,5) << std::endl;
std::cout << foo(100,200,300) << std::endl;
int a=10, b=20;
std::cout << foo(a,b) << std::endl;
return 0;
}
Output
[1]
[2]
[3]
[4]
[5]
5
[100]
[200]
[300]
3
[10]
[20]
2
You have several options.
1) use an ellipse (only way to have unlimited arg list):
int foo(int a1, ...);
Your code will need to parse the ellipse like printf does. you'll be limited to builtin C types.
2) Use multiple templates:
template<typename T1> int foo(T1 a1);
template<typename T1, typename T2> int foo(T1 a1, T2 a2);
// more templates for more arguments
This method us used, usually up to 10 parameters (10 template functions)
3) Use a function with defaults or illegal values so you'll know which is the last valid argument:
int foo(int a1, int a2 = -1, int a3 = -1, int aN = -1);
I want to extract the return type of a function. Problem is, there are other functions with the same name but different signature, and I can not get C++ to select the appropriate one. I know about std::result_of, but from a few tries I have concluded it suffers from the same problem as well. I have heard about a solution involving decltype as well, but I do not know any specifics.
At the moment I am using template metaprogramming to extract the return type from a function pointer type, which works fine for a limited number of parameters (any non-limited solution?), given that extraction of function pointer type works for unambiguous functions.
#include <iostream>
using namespace std;
// ----
#define resultof(x) typename ResultOf<typeof(x)>::Type // might need a & before x
template <class T>
class ResultOf
{
public:
typedef void Type; // might need to be T instead of void; see below
};
template <class R>
class ResultOf<R (*) ()>
{
public:
typedef R Type;
};
template <class R, class P>
class ResultOf<R (*) (P)>
{
public:
typedef R Type;
};
// ----
class NoDefaultConstructor
{
public:
NoDefaultConstructor (int) {}
};
int f ();
int f ()
{
cout << "f" << endl;
return 1;
}
double f (int x);
double f (int x)
{
cout << "f(int)" << endl;
return x + 2.0;
}
bool f (NoDefaultConstructor);
bool f (NoDefaultConstructor)
{
cout << "f(const NoDefaultConstructor)" << endl;
return false;
}
int g ();
int g ()
{
cout << "g" << endl;
return 4;
}
int main (int argc, char* argv[])
{
if(argc||argv){}
// this works since there is no ambiguity. does not work without &
// resultof(&g) x0 = 1;
// cout << x0 << endl;
// does not work since type of f is unknown due to ambiguity. same thing without &
// resultof(&f) x1 = 1;
// cout << x1 << endl;
// does not work since typeof(f()) is int, not a member function pointer; we COULD use T instead of void in the unspecialized class template to make it work. same thing with &
// resultof(f()) x2 = 1;
// cout << x2 << endl;
// does not work per above, and compiler thinks differently from a human about f(int); no idea how to make it correct
// resultof(f(int)) x3 = 1;
// cout << x3 << endl;
// does not work per case 2
// resultof(f(int())) x4 = 1;
// cout << x4 << endl;
// does not work per case 2, and due to the lack of a default constructor
// resultof(f(NoDefaultConstructor())) x5 = 1;
// cout << x5 << endl;
// this works but it does not solve the problem, we need to extract return type from a particular function, not a function type
// resultof(int(*)(int)) x6 = 1;
// cout << x6 << endl;
}
Any idea what syntax feature am I missing and how to fix it, preferably with a solution that works in a simple way, e.g. resultof(f(int))?
I think that this can be done with decltype and declval:
For example: decltype(f(std::declval<T>())).
It's very hard to inspect an overloaded function name without arguments. You can inspect the return types for overloads that differ in arity -- provided that no arity has more than one overload. Even then, turning a hard error (if/when a given arity does have more than one overload) into SFINAE is a pain as it requires writing a trait just for that particular function(!) since overloaded function names can't be passed as any kind of argument. Might as well require user code to use an explicit specialization...
template<typename R>
R
inspect_nullary(R (*)());
template<typename R, typename A0>
R
inspect_unary(R (*)(A0));
int f();
void f(int);
int g();
double g();
typedef decltype(inspect_nullary(f)) nullary_return_type;
typedef decltype(inspect_unary(f)) unary_return_type;
static_assert( std::is_same<nullary_return_type, int>::value, "" );
static_assert( std::is_same<unary_return_type, void>::value, "" );
// hard error: ambiguously overloaded name
// typedef decltype(inspect_nullary(g)) oops;
Given that you're using C++0x, I feel the need to point out that there is (IMO) never a need to inspect a return type beyond typename std::result_of<Functor(Args...)>::type, and that doesn't apply to function names; but perhaps your interest in this is purely academical.
Okay, after a few attempts I managed to work around the std::declval method suggested by Mankarse. I used a variadic class template to fixate the parameters, and used the template deduction of functions to get the return value from a function pointer. Its current syntax is typeof(ResultOf<parameters>::get(function)), unfortunately it is still far from the desired resultof<parameters>(function) form. Will edit this answer if I find a way to further simplify it.
#include <iostream>
#include <typeinfo>
using namespace std;
template <class... Args>
class ResultOf
{
public:
template <class R>
static R get (R (*) (Args...));
template <class R, class C>
static R get (R (C::*) (Args...));
};
class NoDefaultConstructor
{
public:
NoDefaultConstructor (int) {}
};
int f ();
double f (int x);
bool f (NoDefaultConstructor);
int f (int x, int y);
int main (int argc, char* argv[])
{
if(argc||argv){}
cout << typeid(typeof(ResultOf<>::get(f))).name() << endl;
cout << typeid(typeof(ResultOf<int>::get(f))).name() << endl;
cout << typeid(typeof(ResultOf<NoDefaultConstructor>::get(f))).name() << endl;
cout << typeid(typeof(ResultOf<int, int>::get(f))).name() << endl;
typeof(ResultOf<int>::get(f)) d = 1.1;
cout << d << endl;
}
Edit:
Managed to solve it with variadic macros, the syntax is now resultof(f, param1, param2, etc). Without them I couldn't pass the commas between the parameter types to the template. Tried with the syntax resultof(f, (param1, param2, etc)) to no avail.
#include <iostream>
using namespace std;
template <class... Args>
class Param
{
public:
template <class R>
static R Func (R (*) (Args...));
template <class R, class C>
static R Func (R (C::*) (Args...));
};
#define resultof(f, ...) typeof(Param<__VA_ARGS__>::Func(f))
int f ();
double f (int x);
int f (int x, int y);
int main (int argc, char* argv[])
{
resultof(f, int) d = 1.1;
cout << d << endl;
}