473,804 Members | 3,163 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

std::find_if, std::logical_or and short evaluation

Hi,

when the following code is executed

bool Test1();
bool Test2();

....
if (Test1() || Test2()) { ... }
....

Test2 is executed only if Test1 returns false.

I am trying to create a predicate for find_if with the same behaviour:

find_if(iterBeg in,iterEnd, Test1 || Test2)
For do this I have modificated the boost::compose_ f_gx_hx template in
this way:

#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>

/* class for the compose_gx_op_h x adapter
*/
template <class OP1, class OP2, class OP3>
class compose_gx_op_h x_t
: public std::unary_func tion<typename OP2::argument_t ype,
typename OP1::result_typ e>
{
private:
OP1 op1; // process: op2(x) op1 op3(x)
OP2 op2;
OP3 op3;
public:
// constructor
compose_gx_op_h x_t (const OP1& o1, const OP2& o2, const OP3& o3)
: op1(o1), op2(o2), op3(o3) {
}

// function call
typename OP1::result_typ e
operator()(cons t typename OP2::argument_t ype& x) const {
return op2(x) || op3(x);
// return op1(op2(x),op3( x));
}
};

/* convenience functions for the compose_gx_op_h x adapter
*/
template <class OP1, class OP2, class OP3>
inline compose_gx_op_h x_t<OP1,OP2,OP3 >
compose_gx_op_h x (const OP1& o1, const OP2& o2, const OP3& o3) {
return compose_gx_op_h x_t<OP1,OP2,OP3 >(o1,o2,o3);
}

class Test1
: public std::unary_func tion<int,bool>
{
public:
bool operator()(int) const { std::cout << "Test1" << std::endl;
return true; }
};

class Test2
: public std::unary_func tion<int,bool>
{
public:
bool operator()(int) const { std::cout << "Test2" << std::endl;
return false; }
};

int main()
{
std::vector<int > vInt(1,1);

std::find_if(vI nt.begin(), vInt.end(),
compose_gx_op_h x(std::logical_ or<bool>(), Test1(), Test2()));

return 0;
}

The problem is that not a *general* solution because the
logical_operato r is hardcoded (|| in this case) even if it is the
first template parameter.

If I use the commented statement
return op1(op2(x),op3( x));
instead of
return op2(x) || op3(x);
both Test1() and Test2() are always called and there is no short
evaluation.

Many thanks for any help.

Marco.
Jul 22 '05 #1
3 3397
marco_segurini wrote:
when the following code is executed

bool Test1();
bool Test2();

...
if (Test1() || Test2()) { ... }
...

Test2 is executed only if Test1 returns false.

I am trying to create a predicate for find_if with the same behaviour:

find_if(iterBeg in,iterEnd, Test1 || Test2)
For do this I have modificated the boost::compose_ f_gx_hx template in
this way:

#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>

/* class for the compose_gx_op_h x adapter
*/
template <class OP1, class OP2, class OP3>
class compose_gx_op_h x_t
: public std::unary_func tion<typename OP2::argument_t ype,
typename OP1::result_typ e>
{
private:
OP1 op1; // process: op2(x) op1 op3(x)
OP2 op2;
OP3 op3;
public:
// constructor
compose_gx_op_h x_t (const OP1& o1, const OP2& o2, const OP3& o3)
: op1(o1), op2(o2), op3(o3) {
}

// function call
typename OP1::result_typ e
operator()(cons t typename OP2::argument_t ype& x) const {
return op2(x) || op3(x);
// return op1(op2(x),op3( x));
}
};

/* convenience functions for the compose_gx_op_h x adapter
*/
template <class OP1, class OP2, class OP3>
inline compose_gx_op_h x_t<OP1,OP2,OP3 >
compose_gx_op_h x (const OP1& o1, const OP2& o2, const OP3& o3) {
return compose_gx_op_h x_t<OP1,OP2,OP3 >(o1,o2,o3);
}

class Test1
: public std::unary_func tion<int,bool>
{
public:
bool operator()(int) const { std::cout << "Test1" << std::endl;
return true; }
};

class Test2
: public std::unary_func tion<int,bool>
{
public:
bool operator()(int) const { std::cout << "Test2" << std::endl;
return false; }
};

int main()
{
std::vector<int > vInt(1,1);

std::find_if(vI nt.begin(), vInt.end(),
compose_gx_op_h x(std::logical_ or<bool>(), Test1(), Test2()));

return 0;
}

The problem is that not a *general* solution because the
logical_operato r is hardcoded (|| in this case) even if it is the
first template parameter.

If I use the commented statement
return op1(op2(x),op3( x));
instead of
return op2(x) || op3(x);
both Test1() and Test2() are always called and there is no short
evaluation.


It's a known problem. For example, if you overload operator || or
operator &&, you cannot make them behave like the built-in ones do
(WRT short-cutting or specific order of evaluation or existence of
a sequence point). It's a limitation of the language.

In order to achieve what you want you'd have to basically repeat
what the language defines about the logical operators. You can do
it using specialisations . Instead of making a generic template,
you should probably make two templates, one for OR and one for AND.
The 'OR' will do as you wrote

return op2(x) || op3(x);

and the 'AND' will do

return op2(x) && op3(x);

Otherwise, your solution is declaring "operator traits" with the order
of operand evaluation either predefined or undefined, and then, again,
implement variations of the execution based on the traits:

if (op1::traits::d o_second_if_fir st_false) {
bool x = op2(x);
if (!x)
return op3(x);
else
return x;
}
else if (op1::traits::d o_second_if_fir st_true) {
bool x = op2(x);
if (x)
return op3(x);
else
return false;
}
else
return op1(op2(x), op3(x));

Then you could (optionally) define those traits (or, specialise them)
for 'or' and 'and' and use generic ones for anything else.

Victor
Jul 22 '05 #2
> if (Test1() || Test2()) { ... }
...

Test2 is executed only if Test1 returns false.

I am trying to create a predicate for find_if with the same behaviour:

find_if(iterBeg in,iterEnd, Test1 || Test2)


If you are not hooked to the find_if there is another way of implementing
such a behaviour
I once used something like:
---------------
for(LIST::itera tor i=l.begin();i!= l.end();i++)
if(pred1(*i) || pred2(*i))
{
//do stuff
}
---------------
//jota
Jul 22 '05 #3
marco_segurini wrote:
[snip]
instead of
return op2(x) || op3(x);
both Test1() and Test2() are always called and there is no short
evaluation.


ALl of that seems a lot of work for a simple:

bool Test()
{
return Test1() || Test2();
}

find_if( iterBegin, iterEnd, Test )
--
Karl Heinz Buchegger
kb******@gascad .at
Jul 22 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
1880
by: Antti Granqvist | last post by:
Hello! I have following object relations: Competition 1--* Category 1--* Course 1 | | * Course
16
16434
by: Khuong Dinh Pham | last post by:
I have the contents of an image of type std::string. How can I make a CxImage object with this type. The parameters to CxImage is: CxImage(byte* data, DWORD size) Thx in advance
3
2143
by: ram | last post by:
hi all, apart from readability, and not wanting the otherwise different statements to be assumed as one single loong statement what are the pros/cons of both snippets? i tried this out on a small piece of code and the latter part using short circuiting takes about half the time as the if else version; gcc 3.2 , amdk6-2 running vectorlinux; cheers
12
6115
by: Filipe Sousa | last post by:
Hi! Could someone explain to me why this operation is not what I was expecting? int main() { int x = 2; std::cout << x << " " << x++ << std::endl; return 0; }
5
5144
by: wolverine | last post by:
Hi I want to know how to use basic_string with unsigned short (I have mentioned below why i have to do this). Could any tell me some good references in this topic. I am new to creating a new basic_string class. #include <string> #include<iostream> using namespace std;
10
5653
by: Jim Langston | last post by:
Is the following well defined? size_t IntVal = 65537; unsigned short Length; if ( IntVal static_cast<unsigned short>( -1 ) ) { std::cout << "Value too long to fit in a short" << std::endl; } else
10
7653
by: JDT | last post by:
Hi, The following find_if works fine to me except that I want the internal individual comparison performed backward (from m+5, m+4, ..., to m). I can use reverse() to reverse the array first but that introduces overhead (a copy of the whole array). It seems that I can use a reverse iterator but the array m is not a standard STL container such as a vector. Is it possible? Your help is much appreciated. float m;
7
2503
by: Peter | last post by:
I know the order of construction of member and base class objects. My question is the following: Is the order of evaluation of argument lists for these constructors also defined? E.g. can I assume that the following code is exceptions safe? Assuming that the constructor of A, B or C may throw? Can I assume that B is created after the constructor of m_sA has been called?
11
4849
by: tech | last post by:
Hi, I need a function to specify a match pattern including using wildcard characters as below to find chars in a std::string. The match pattern can contain the wildcard characters "*" and "?", where "*" matches zero or more consecutive occurrences of any character and "?" matches a single occurrence of any character. Does boost or some other library have this capability? If boost does have this, do i need to include an entire
0
9585
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10338
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10323
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10082
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9161
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6856
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5658
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4301
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2997
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.