why is this code invalid?. I don't know if I am using the lambda sintax correctly, but based on other posts, it looks fine.
struct foo{
static int faa(int x);
};
int foo::faa(int x){
bool isCon = []() {
return true;
};
return isCon();
}
Lambdas have indeterminate type, so you can't know which type will one have. Obviously, the lambda you defined won't be of type bool (it may return a bool, but it's not one), so you would do this instead:
struct foo{
static int faa(int x);
};
int foo::faa(int x){
auto isCon = []()->bool {
return true;
};
return isCon();
}
Here, the auto keyword tells the compiler to deduce the type for you. The ->bool expression tells the compiler that the lambda will return a bool.
However, your foo::faa() function returns an int, so a cast may ocurr because your lambda may return a bool (which has nothing to do with the question, but watch out).
Related
I have a group of functions which perform similar action on different input parameter classes ParamX, ParamY, ParamZ. They have a general form like:
Result funcX(ParamX param){
auto result = param.getX(); // param.getY() in case of ParamY
// check result is valid
if(!result.valid()){
// print a log message for ParamX
return {};
}
return result.value();
}
Result is a templated struct like Result<ParamX>, based on the type of input parameter class ParamX.
Also note that each param will call a completely different function param.getX(), param.getY(), param.getZ()
So given I have several different functions funcX, funcY, funcZ, each acting on ParamX, ParamY, ParamZ separately, how do I convert this into a single template function?
Also note that in the future, any developer can make another ParamA, ParamB .... class with different getA(), getB() methods, so nothing is fixed.
given I have several different functions funcX, funcY, funcZ, each acting on ParamX, ParamY, ParamZ separately, how do I convert this into a single template function?
You can make use of function templates and auto type deduction(using the auto type specifier in the return type) as shown below:
template<typename ParamX>
//--vvvv---------------------->auto type deduction
auto funcX(ParamX param){
auto result = param.getX();
// check result is valid
if(!result.valid()){
// print a log message for ParamX
// add appropriate return statement if needed
}
return result.value();
}
Edit
Now since you've edited your question to specify that each of the passed arguments will have their own getter, you can use the following code.
Solution 1
Here we make use of pointer to member function as the second argument to the function template.
#include <iostream>
#include<string>
struct Name
{
bool valid()
{
return true;
}
int value ()
{
return 5;
}
};
struct Server1
{
Name getX()
{
std::cout<<"getX called"<<std::endl;
return Name();
}
};
struct Server2
{
Name getY()
{
std::cout<<"getY called"<<std::endl;
return Name();
}
};
template<typename ParamX, typename RType>
//--vvvv---------------------->auto type deduction
auto funcX(ParamX param,RType (ParamX::*callable)()){
std::cout<<"funcX called"<<std::endl;
auto result = ((param.*callable)());
// check result is valid
if(!result.valid()){
// print a log message for ParamX
// add appropriate return statement if needed
}
return result.value();
}
int main()
{
funcX(Server1(), &Server1::getX);
funcX(Server2(), &Server2::getY);
return 0;
}
Demo
The output of the above is:
funcX called
getX called
funcX called
getY called
Solution 2
This is a variation of solution 1 above. Here the second argument of the function template is taken as a reference to const.
#include <iostream>
#include<map>
#include<string>
#include<vector>
struct Name
{
bool valid()
{
return true;
}
int value ()
{
return 5;
}
};
struct Server1
{
Name getX()
{
std::cout<<"getX called"<<std::endl;
return Name();
}
};
struct Server2
{
Name getY()
{
std::cout<<"getY called"<<std::endl;
return Name();
}
};
template<typename ParamX, typename Callable>
//--vvvv---------------------->auto type deduction
auto funcX(ParamX param, const Callable& callable){
std::cout<<"funcX called"<<std::endl;
auto result = (param.*callable)();
// check result is valid
if(!result.valid()){
// print a log message for ParamX
// add appropriate return statement if needed
}
return result.value();
}
int main()
{
funcX(Server1(), &Server1::getX);
funcX(Server2(), &Server2::getY);
return 0;
}
Demo
Assuming this was requirements above:
template <typename TParam,typename TResult>
TResult funcX(TParam param){
auto result = param.getX();
// check result is valid
if(!result.valid()){
// print a log message for ParamX
return {};
}
return result.value();
}
Note if you want to generalize coordinate you can invoke template compile time polymorpism by implying a member(in this case its getx of tparam). If you want to generalize u just need to agree on a name.
Alternatively if performance not important u can do runtime polymorpism via a virtual member. This doesnt require a template.
If u want a complicated template example have a look at my non blocking network templates here:
https://bitbucket.org/ptroen/crossplatformnetwork/src/master/OSI/Application/Stub/HTTPSServer/httpsserver.cc
It depends on the properties of ParamX, Result<ParamX>, and the other types to some extent.
But, assuming (since you haven't specified)
You have a templated type Result such that Result<ParamX> is the result corresponding to a ParamX, and Result<ParamY> is the result corresponding to a ParamY
Result<ParamX> is default constructible (so it will be constructed in return {} for a function that returns Result<ParamX>;
ParamX, ParamY, etc all have a member function getX();
The return type of that getX() function is implicitly convertible to Result<ParamX>;
The return type of that getX() function has a member function named valid() that returns an integral type (where a zero or false return indicates invalid);
You might do something like
template<class Param> Result<Param> func(Param param)
{
auto result = param.getX();
// check result is valid
if(!result.valid())
{
// print a log message
return {};
}
return result.value();
}
Then, to use that function you might do;
ParamX px;
Result<ParamX> result = Result(px); // Result(px) is equivalent to Result<ParamX>(px)
auto result2 = Result(px); // compiler will deduce the type of result2 as Result<ParamX>
ParamY py;
Result<ParamY> result = Result(py); // Result(py) is equivalent to Result<ParamY>(py)
Note I'm making a lot of assumptions in the above, to fill in information you have not provided. You need to make a similar set in your code and (more importantly) ensure they are true.
I have a function that should return an object of class A if i is positive, return an integer else.
This is a strong simplified example, and i can not use overloading !
#include <iostream>
template <typename T>
T& function(int i){
T res;
if (i>0){
A res = 1;
}
else{
int res = 5;
}
return res;
}
int main(){
A res1 = function(5);
int res2 = function(-5;)
return 0;
}
Types are static, determined when the code is compiled, so you can't have a different return type depending on a run-time value. A function can only return one type.
One option is to use a discriminated union; a union of the different types you want to support, along with an enumerated value to indicate which type is active. This is quite tricky to implement if you want to support general class types, so you might want to look at Boost's Variant library. For example:
boost::variant<int,T> function(int i) {
if (i>0)
return A{1};
else
return int{5};
}
int main() {
A res1 = boost::get<A>(function(5));
int res2 = boost::get<int>(funtion(-5);
}
Another option might be to provide a set of callback functions for different types, and handle the value there rather than returning it. For example:
template <typename Callback>
void function(int i, Callback & callback)
if (i>0)
callback(A{1});
else
callback(int{5});
}
struct MyCallback {
void operator()(A const &) {/* do something with A */}
void operator()(int) {/* do something with int */}
};
int main() {
MyCallback callback;
function(5, callback); // calls callback for A
function(-5, callback); // calls callback for int
}
What you are trying to do is impossible. Your function can only have one return type. You could pass in an A variable and an integer variable by reference and have one or the other set by the function but that's the closest you're going to be able to get. I'm rather unsure of what you are trying to accomplish though.
C++ simply does not support this.
A better solution would be:
bool function(int i, int &intResult, A &AResult)
{
if (i > 0)
{
AResult = A(1);
// Or whatever other code you need to place the result in AResult
return true;
}
intResult = 5;
return false;
}
You need to pass both an int and an A to receive the possible return values, and by inspecting the bool that's returned you know which one was filled in.
The pseudo code for what I want to do is:
function<bool(int)> getFunc(type) // get a function depending on what type is passed
problem is the function to return must be declared as static? As a result, I can't access object properties. So I need to pass them into the function? Thus, the original function to return might look like:
bool func1(int)
bool func2(int)
Now needs to be injected with other objects/arguments it need to run ...
bool func1(int, Class1)
bool func2(int, Class2)
So how do I define the return type of getFunc? Or maybe theres a better way?
UPDATE
In the above, func* functions are actually: has*(). eg.
hasStmtsUsing(variable)
hasVariablesUsed(stmt)
And to determine if the condition is true, it uses an object eg. uses. Then there are other similar has*() functions like hasStmtsModifying(variable) that uses an object modifies. uses and modifies are objects of different types, and originally, they are object members, thus dont need to be passed in. Now since the functions are static, they need to be passed in.
While writing this, I am thinking what I need is some kind of dependency injector? Maybe I pass in DI and call DI.getX() functions?
Maybe I'm misunderstanding something, but isn't all you need to use a memberfunction where you bind() the first parameter?
class X {
bool f1(int);
bool f2(int);
};
X x;
function<bool(int)> f = bind(&X::f1, &x);
Here's an example of how it can be done with lambdas in C++11:
#include <cassert>
#include <functional>
#include <iostream>
struct Class1 {
};
struct Class2 {
};
bool func1(int,Class1)
{
return true;
}
bool func2(int,Class2)
{
return false;
}
inline std::function<bool(int)> getFunc(Class1 obj1)
{
return [=](int x){ return func1(x,obj1); };
}
inline std::function<bool(int)> getFunc(Class2 obj2)
{
return [=](int x){ return func2(x,obj2); };
}
int main(int,char**)
{
Class1 obj1;
std::function<bool(int)> f1 = getFunc(obj1);
Class2 obj2;
std::function<bool(int)> f2 = getFunc(obj2);
assert(f1(0)==true);
assert(f2(0)==false);
return 0;
}
I've a problem on this code:
template <typename T>
void dosth(T& value,const T& default_value)
{
if (condition)
value = 10;
else
value = default_value;
}
When I call that with
enum {
SITUATION1,
STIUATION2
};
int k;
dosth(k,SITUATION1);
the compiler (g++ 4.5) says
no matching function for call to 'dosth(int&,)'
Why doesn't the compiler automatically cast the enum into an int?
Your problem is due to the fact that the template cannot be instantiated from the function arguments that you supply. No implicit conversion to int occurs, because there's no function to call at all.
If you cast instead of attempting to rely on implicit conversion, your program will work:
dosth(k, static_cast<int>(SITUATION1));
Or, if you provide the function template's arguments explicitly, then the function argument will be converted implicitly as you expect, and your program will work:
dosth<int>(k, SITUATION1);
Would this be better for enums?
class Situations
{
private:
const int value;
Situations(int value) : value(value) {};
public:
static const Situations SITUATION1() { return 1; }
static const Situations SITUATION2() { return 2; }
int AsInt() const { return value; }
};
Will enable type safety. Then use it to create a type safte template.
i.e. Value for pass or fail.
Why does the following code work?
class foo {
public:
template <typename F>
int Map(F function) const {
return function(2);
}
};
int Double(int n) {
return 2*n;
}
int main(){
foo f;
int n = f.Map(Double);
}
My understanding is that the function accepting the function pointer must have format such as:
void foo(int (*ptf)(int))
So the Map function should look like
int Map(int (*ptf)(int)){
return (*ptf)(2);
}
does the it somehow resolve the function at run-time or at compile-time through template?
the above code was compiled and ran in vc++ 2010
Template are a compile-time concept, so of course it will be resolved during compile time (if what you mean is the template parameter substitution). Try passing something which you can't call like function(2), e.g., some int. This will yield a compile-time error. After substitution, your function will look like
int Map(int (*function)(int)){
return function(2);
}
You don't explicitly need to dereference a function pointer, because both function(2) and (*function)(2) are immediatly converted to a so-called function designator. That itself is dereferenceable again and you can build an endless chain: (***********function)(2) will still work and is still the same as function(2) and (*function)(2).