This question already has answers here:
Is there any way in C++ to refer to a function template while neither calling it nor supplying its template parameters?
(4 answers)
Convert template function to generic lambda
(2 answers)
How do I make a functor out of an arbitrary function?
(2 answers)
Closed 2 years ago.
I have a function returning a std::pair, which I want to use to call an overloaded member function. I am not aware of any way to unpack a tuple in-place (which I'd prefer), so std::apply is my best bet, I think.
This works with a combination of tuple_cat and forward_as_tuple when the member function is not overloaded, but otherwise, the compiler complains about an unresolved overload.
That is understandable, given that std::apply just takes a function pointer, but I'd still like to know whether it can be made to work in a readable way.
Here's some example code:
#include <iostream>
#include <tuple>
#include <utility>
std::pair<int, int> func() { return { 0, 1 }; }
class MyClass {
public:
int memFun(int);
int memFun(int, int);
};
int MyClass::memFun(int i){ return 2*i; }
int MyClass::memFun(int a, int b){ return a+b; }
int main(){
MyClass myClass;
/* works */
std::pair pair { func() };
int number { myClass.memFun( pair.first, pair.second ) };
/* doesn't work (unresolved overload) */
int number { std::apply(
&MyClass::memFun,
std::tuple_cat( std::forward_as_tuple(myClass), func() )
) };
std::cout << number << "\n";
return 0;
}
Is there an elegant (=readable) way to do this without a temporary?
I only found this question and so far don't think it fully applies.
Related
This question already has answers here:
Why do I have to access template base class members through the this pointer?
(3 answers)
ISO C++ Standard - rules regarding examining dependent base. Why?
(1 answer)
Closed 8 months ago.
This code doesn't compile:
#include<iostream>
using namespace std;
template<class T>struct Base {
void f(int) { cout << "Base::f() int\n"; }
};
template<class T>struct Derived:Base<T> {
void g(int i) { f(i); } // should be this->f(i) to pass compile
};
int main(){
Derived<char> obj;
obj.g(1); // cfunction short
return 0;
}
I googled and search on stackoverflow, it says that in the error-line, I should use write either
void g(int i) { this->f(i); }
or
void g(int i) { Base<T>::f(i); }
Yes, they work. I tried none-template version, doesn't need this complex qualifier. As long as both f() and g() doesn't use any template type parameter, I didn't think of a rule on template deduction upon these 2 functions.
Is this some hidden rule behind template resolution that I should add extra qualifier, and why my original code fail to compile?
This question already has answers here:
How do I specify a pointer to an overloaded function?
(6 answers)
Closed 3 years ago.
How do we create a std::function object for overloaded member functions in a class? std::function object can be created for a non-overloaded member function as shown.
Sample code is attached as shown below
#include<iostream>
#include<functional>
class X
{
public:
X(){}
virtual ~X(){}
void foo1(char c)
{std::cout<<"X::foo1(char c)\n";}
void foo2(char c)
{std::cout<<"X::foo2(char c)\n";}
void foo2(int i)
{std::cout<<"X::foo2(int i)\n";}
}x;
int main()
{
std::function<void(X*,char)> f1=&X::foo1;
f1(&x,'a');
/* //The following code doesn't work
std::function<void(X*,char)> f2=&X::foo2;
f2(&x,'a');
*/
return 0;
}
Following error is given :
conversion from '' to non-scalar type 'std::function' requested
You need to be explicit about the signature of the overloaded function you intend to use:
std::function<void(X*,char)> f2 = static_cast<void (X::*)(char)>(&X::foo2);
As an alternative, use a lambda:
std::function<void(X*,char)> f3 =
[](X *instance, char c){ return instance->foo2(c); };
This question already has answers here:
Ambiguous overload on argument-less variadic templates
(2 answers)
Closed 4 years ago.
I want to create a "grand total" function by summing several other functions together. This can be done at compile time, so I thought a recursive variadic function template would be a good solution. My code so far:
int One(){return 1;}
int Two(){return 2;}
int Three(){return 3;}
using func_t = int(void);
//Base case
template <func_t F>
int Total() {
return F();
}
template <func_t F, func_t... Fs>
int Total() {
return F() + Total<Fs...>();
}
int main(int argc, char *argv[])
{
cout << Total<One, Two, Three>() << endl;
return 0;
}
However, I get MSVC compiler error C2668: 'Total': ambiguous call to overloaded function; could be int Total<int Three(void),>(void) or int Total<int Three(void)>(void)
I don't understand why the compiler has two similar candidates for my function template, the only difference being that one has an extra comma.
Your base case declaration is incorrect, and results in the compiler being unable to differentiate between a call to your base case and a call to your recursive base.
If you make your base case an empty list of templates, there is no longer ambiguity.
template <class none = void>
int Total() {
return 0;
}
This question already has answers here:
Is auto as a parameter in a regular function a GCC 4.9 extension?
(2 answers)
Closed 5 years ago.
I want to declare a function that takes as argument a function (or lambda) with a specific prototype.
The first try is:
#include <iostream>
using namespace std;
int test(int (&val)(int)) {
return val(2);
}
int main() {
cout << test([](int v){
return v+100;
});
return 0;
}
witch results in error: invalid initialization of non-const reference of type 'int (&)(int)' from an rvalue of type 'main()::<lambda(int)>'
I tried to add const specified to the type but I don't know where exactly so I tried the following that works with GCC (-std=c++14), however I suspect it is illegal since it fails with clang:
int test(const auto& val) {
return val(2);
}
I know I can use template or function pointers or std::function to achieve the same, then please consider this a didactic question. I want to know what does GCC deduce the type of val to, in the second example above (int test(const auto& val)).
template <typename F>
int test(F val) {
return val(2);
}
int test(int val(int)) {
return val(2);
}
int test(std::function<int(int)> val) {
return val(2);
}
I want to declare a function that takes as argument a function (or lambda) with a specific prototype.
Closures generated by lambda expression have a unique and anonymous type. They could also be generic (i.e. template operator()). There is no "easy" way of declaring a function accepting lambdas with a specific prototype. Your best bet is either using a constrained template parameter with something like std::is_invocable or using some sort of type erasure like function_view.
Note: if your lambda is captureless it is implicitly convertible to a function pointer. E.g.
int test(int (*)(int)) { }
test([](int) -> int {}); // OK
test([i = 0](int) -> int {}); // compile-time error
I want to know what does GCC deduce the type of val to, in the second example.
int test(int val(int))
...is equivalent to...
int test(int (*val)(int))
In fact, having both of them in the same scope results in a redefinition error:
int test(int val(int)) {
return val(2);
}
int test(int (*val)(int)) {
return val(2);
}
prog.cc:5:5: error: redefinition of 'test'
int test(int (*val)(int)) {
^
prog.cc:1:5: note: previous definition is here
int test(int val(int)) {
^
This question already has answers here:
Overload resolution with std::function
(2 answers)
Closed 6 years ago.
consider some code:
void foo() { }
bool bar() { return true; }
struct S
{
void operator=(std::function<void()> f){f();};
void operator=(std::function<bool()> f){f();};
};
int main() {
S s;
s = foo; // ok
s = bar; // error: use of overloaded operator '=' is ambiguous
}
How can I make this example unambiguous?
The problem you're running into is that std::function<void(Args...)> is allowed to discard return types - so both std::function<void()> and std::function<bool()> can be constructed from a bool(*)(). The latter will forward through the return from bar, but the former will just discard it. That's perfectly valid behavior, but causes this to be ambiguous.
What you probably want is to avoid std::function altogether:
template <class F>
void operator=(F f) { f(); }