Operator precedence change - c++

The following used to build OK on VS2008 but on VS2013, it moans. OK in g++.
#include <sstream>
int main()
{
int a = 2, b = 5;
std::ostringstream oss;
oss << a == 0 ? a : b;
}
The error message is
1>u:\precedence\precedence.cpp(7): error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::basic_ostream<char,std::char_traits<char>>' (or there is no acceptable conversion)
1> c:\program files\microsoft visual studio 12.0\vc\include\exception(497): could be 'bool std::operator ==(const std::exception_ptr &,const std::exception_ptr &)' [found using argument-dependent lookup]
1> c:\program files\microsoft visual studio 12.0\vc\include\exception(502): or 'bool std::operator ==(std::nullptr_t,const std::exception_ptr &)' [found using argument-dependent lookup]
1> c:\program files\microsoft visual studio 12.0\vc\include\exception(507): or 'bool std::operator ==(const std::exception_ptr &,std::nullptr_t)' [found using argument-dependent lookup]
1> c:\program files\microsoft visual studio 12.0\vc\include\system_error(402): or 'bool std::operator ==(const std::error_code &,const std::error_condition &) throw()' [found using argument-dependent lookup]
1> c:\program files\microsoft visual studio 12.0\vc\include\system_error(410): or 'bool std::operator ==(const std::error_condition &,const std::error_code &) throw()' [found using argument-dependent lookup]
1> while trying to match the argument list '(std::basic_ostream<char,std::char_traits<char>>, int)'
It works on both versions if the output statement is changed to
oss << (a == 0? a: b);
I can force a different error in VS2008 if a constant is not used: something like
int zero = 0;
oss << a == zero? a: b;
Just wondering why there is an error when a constant is not used.
Edit Managed to get an warning with g++ with -Wall.

The expression the compiler sees due to the precedence is, in all cases:
((oss << a) == 0) ? a : b;
Now oss << a returns oss. How can you compare oss with 0? It has an implicit conversion operator operator void *.
VS2013 presumably replaced that with explicit operator bool for C++11 (the whole point of which was so that these hard-to-find bugs don't occur). libstdc++ has not done this replacement to my knowledge. It must in order to conform with C++11.
Now why doesn't zero compile? zero is not a null pointer constant, but 0 is. Thus, the latter can be compared to the pointer returned by operator void *.
In any case, the simple way to fix this so it should work properly with any conforming implementation is to add parentheses:
oss << (a == 0 ? a : b);

It appears that the compiler is interpreting it different.
Based on the error, I would suspect that the compiler is interpreting the line of code like this
(oss << a) == 0 ? a : b;
So when you put in the parens there was no longer any way it could interpret it that way, and you got the expected results.
I suspect that this would also work.
oss << (a == 0) ? a : b;

Related

Different iterator behavior of raw array and std::array on clang++ and VC++

Consider following program:
#include <iostream>
#include <algorithm>
#include <array>
bool greater_than_seven(int i) {
return i > 5;
}
bool divisible_by_five(int x) {
return ((x%5)==0);
}
int main() {
int arr[]{3,6,9,12,15};
std::cout<<"Enter a number you want to search: ";
int num;
std::cin>>num;
auto result(std::find(std::begin(arr),std::end(arr),num));
if(result != std::end(arr))
std::cout<<"arr contains: "<<num<<'\n';
else
std::cout<<"arr doesn't contain: "<<num<<'\n';
for(result=std::find_if(std::begin(arr),std::end(arr),greater_than_seven);result!=std::end(arr);++result)
std::cout<<*result<<' ';
std::cout<<'\n';
std::array<int,4> x{33,66,99,55};
for(result=std::find_if_not(std::begin(x),std::end(x),divisible_by_five);result!=std::end(x);++result)
std::cout<<*result<<'\n';
}
This program compiles fine on g++ & clang++.
See live demo here ( g++ 5.4.0 )
See live demo here ( clang++ 3.8.0 )
But it gives horrible compiler error on Microsoft Visual C++ compiler.
See live demo here ( Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x64 )
Error(s):
source_file.cpp(27): error C2440: '=': cannot convert from 'std::_Array_iterator<_Ty,4>' to 'int *'
with
[
_Ty=int
]
source_file.cpp(27): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
source_file.cpp(27): error C2679: binary '!=': no operator found which takes a right-hand operand of type 'std::_Array_iterator<_Ty,4>' (or there is no acceptable conversion)
with
[
_Ty=int
]
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\exception(343): note: could be 'bool std::operator !=(const std::exception_ptr &,const std::exception_ptr &) throw()' [found using argument-dependent lookup]
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\exception(348): note: or 'bool std::operator !=(std::nullptr_t,const std::exception_ptr &) throw()' [found using argument-dependent lookup]
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\exception(353): note: or 'bool std::operator !=(const std::exception_ptr &,std::nullptr_t) throw()' [found using argument-dependent lookup]
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\system_error(388): note: or 'bool std::operator !=(const std::error_code &,const std::error_code &) noexcept' [found using argument-dependent lookup]
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\system_error(395): note: or 'bool std::operator !=(const std::error_code &,const std::error_condition &) noexcept' [found using argument-dependent lookup]
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\system_error(402): note: or 'bool std::operator !=(const std::error_condition &,const std::error_code &) noexcept' [found using argument-dependent lookup]
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\system_error(409): note: or 'bool std::operator !=(const std::error_condition &,const std::error_condition &) noexcept' [found using argument-dependent lookup]
source_file.cpp(27): note: while trying to match the argument list '(int *, std::_Array_iterator<_Ty,4>)'
with
[
_Ty=int
]
So the question is which compiler is right here according to C++ standard ? Is this bug in VC++ compiler ?
Is this bug in VC++ compiler ?
No.
You're assigning and comparing the iterators got from std::begin and std::end on raw array (i.e. result, std::find(std::begin(arr),std::end(arr),num)) and std::array (i.e. std::find_if_not(std::begin(x),std::end(x),divisible_by_five) and std::end(x)), you might be supposing that the types of them are the same.
For raw arrays it'll be T*, i.e. int* for this case, this is guaranteed. The problem is that the standard doesn't specify the exact type of std::array::iterator, it just says it must satisfy the requirements of RandomAccessIterator. Gcc and Clang choose the int* as its type, this is fine because the raw pointer satisfy the requirements. VC implements it as a customized class, this is fine too so long as the type satisfies the requirements. And note that that type doesn't have to be able to convert to int*; the standard doesn't require that at all.
So even your code works with Gcc and Clang, it's not guaranteed.

What does the istream extraction operator >> return?

I'm trying to get Solipsis to compile in Visual Studio 2017(it was written for VS 2005)
I can't figure out what this code is trying to do:
template<typename T>
bool from_string( const char* Str, T & Dest )
{
// créer un flux à partir de la chaîne donnée
std::istringstream iss( Str );
// tenter la conversion vers Dest
return iss >> Dest != 0;
}
It gets the following error
1>c:\users\root\source\repos\solipsis3d\sources\modelers\mdlrtools\include\SolipsisErrorHandler.h(91): error C2678: binary '!=': no operator found which takes a left-hand operand of type 'std::basic_istream<char,std::char_traits<char>>' (or there is no acceptable conversion)
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\include\exception(347): note: could be 'bool std::operator !=(const std::exception_ptr &,const std::exception_ptr &) throw()' [found using argument-dependent lookup]
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\include\exception(352): note: or 'bool std::operator !=(std::nullptr_t,const std::exception_ptr &) throw()' [found using argument-dependent lookup]
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\include\exception(357): note: or 'bool std::operator !=(const std::exception_ptr &,std::nullptr_t) throw()' [found using argument-dependent lookup]
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\include\system_error(379): note: or 'bool std::operator !=(const std::error_code &,const std::error_code &) noexcept' [found using argument-dependent lookup]
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\include\system_error(384): note: or 'bool std::operator !=(const std::error_code &,const std::error_condition &) noexcept' [found using argument-dependent lookup]
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\include\system_error(389): note: or 'bool std::operator !=(const std::error_condition &,const std::error_code &) noexcept' [found using argument-dependent lookup]
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\include\system_error(394): note: or 'bool std::operator !=(const std::error_condition &,const std::error_condition &) noexcept' [found using argument-dependent lookup]
1>c:\users\root\source\repos\solipsis3d\sources\modelers\mdlrtools\include\SolipsisErrorHandler.h(91): note: or 'built-in C++ operator!=(bool, int)'
1>c:\users\root\source\repos\solipsis3d\sources\modelers\mdlrtools\include\SolipsisErrorHandler.h(91): note: while trying to match the argument list '(std::basic_istream<char,std::char_traits<char>>, int)'
1>src\Object3D.cpp(220): note: see reference to function template instantiation 'bool Solipsis::from_string<bool>(const char *,T &)' being compiled
1> with
1> [
1> T=bool
1> ]
1>c:\users\root\source\repos\solipsis3d\sources\modelers\mdlrtools\include\SolipsisErrorHandler.h(91): error C2446: '!=': no conversion from 'int' to 'std::basic_istream<char,std::char_traits<char>>'
1>c:\users\root\source\repos\solipsis3d\sources\modelers\mdlrtools\include\SolipsisErrorHandler.h(91): note: Constructor for class 'std::basic_istream<char,std::char_traits<char>>' is declared 'explicit'
1>SolipsisErrorHandler.cpp
In human language what is the return value of the '>>' operator(when used as for extraction not bit shift)? What has changed about it since VS 2005 that makes the code snippet not work?
I can't figure out what this code is trying to do:
The code is trying to return whether the stream extraction was successful or not.
What does the istream extraction operator >> return?
It is not the case that the return type of the operator is breaking your compilation, but rather because of a change in behaviour since C++11.
Prior to C++11 (say with VS2005) you could check for success/failure by comparing the istream object with true/false.
return iss >> Dest != 0;
You can't do that with a C++11 compilation (say with VS2017), and the reasons are given in the excellent answer to the suggested duplicate question:
Evaluating stream operator >> as boolean
Rather modernise your function by casting to a boolean.
return bool(iss >> Dest);

SFML and STL: What's wrong with my code?

I have the following code snippets:
void RemoveButton::triggerAction(team &team, unsigned int index)
{
switch (mAction)
{
case Action::remove:
{
//team.mTeamMembers.erase(std::remove(team.mTeamMembers.begin(), team.mTeamMembers.end(), team.mTeamMembers.at(index)), team.mTeamMembers.end());
team.mTeamMembers.erase(team.mTeamMembers.begin() + index);
for (unsigned int i = index; i < team.mTeamMembers.size(); i++)
{
team.mTeamMembers[i].mRemoveButton->getText().move(0.0f, -30.0f);
team.mTeamMembers[i].mText.move(0.0f, -30.0f);
}
team.mAddPosition.y -= 30.0f;
break;
}
default:break;
}
}
class team
{
public:
size_t teamNumber;
std::vector<AddButton> mAddButtons;
std::vector<teamRecord> mTeamMembers;
sf::Sprite mBorder;
sf::Text mText;
Selector<AddButton> mAddButtons_Selector;
sf::Vector2f mAddPosition;
Selector<teamRecord> mTeamMembers_Selector;
team(sf::Vector2f borderPosition, sf::Vector2f removeButtonsPosition, sf::Vector2f textPosition, size_t teamNumb, std::string text);
};
How should I erase an element from the team.mTeamMembers STL vector? The way I do it currently results in seemingly random execution errors, specifically when clicking the non-existent sprite of a deleted button. The commented line that uses std::remove is not compiled, and I do not understand why. As I'm feeling confused a.f. , can someone please shine some light here? Here's the build log while using std::remove, as recommended by some users on this forum:
1>------ Build started: Project: Complex OOP Menus, Configuration: Release Win32 ------
1> RemoveButton.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\algorithm(1454): error C2678: binary '==': no operator found which takes a left-hand operand of type 'teamRecord' (or there is no acceptable conversion)
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\system_error(389): note: could be 'bool std::operator ==(const std::error_condition &,const std::error_condition &) noexcept'
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\system_error(381): note: or 'bool std::operator ==(const std::error_condition &,const std::error_code &) noexcept'
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\system_error(373): note: or 'bool std::operator ==(const std::error_code &,const std::error_condition &) noexcept'
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\system_error(365): note: or 'bool std::operator ==(const std::error_code &,const std::error_code &) noexcept'
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\exception(339): note: or 'bool std::operator ==(const std::exception_ptr &,std::nullptr_t) throw()'
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\exception(334): note: or 'bool std::operator ==(std::nullptr_t,const std::exception_ptr &) throw()'
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\exception(329): note: or 'bool std::operator ==(const std::exception_ptr &,const std::exception_ptr &) throw()'
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\algorithm(1454): note: while trying to match the argument list '(teamRecord, const teamRecord)'
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\algorithm(1467): note: see reference to function template instantiation '_FwdIt std::_Remove_unchecked<teamRecord*,_Ty>(_FwdIt,_FwdIt,const _Ty &)' being compiled
1> with
1> [
1> _FwdIt=teamRecord *,
1> _Ty=teamRecord
1> ]
1> ..\Data\Source\RemoveButton.cpp(24): note: see reference to function template instantiation '_FwdIt std::remove<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<teamRecord>>>,teamRecord>(_FwdIt,_FwdIt,const _Ty &)' being compiled
1> with
1> [
1> _FwdIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<teamRecord>>>,
1> _Ty=teamRecord
1> ]
If there is not enough information here, I could post the github link to my project, but it's pretty big and it would take time to sift through the code.
Using std::remove() doesn't make any sense to me if you already know the position/offset and you only want to remove a single entry.
You're receiving your error with std::remove() most likely due to the fact that there's no equality operator (operator ==) defined for your teamRecord class (or it just isn't found).
The way I do it currently results in seemingly random execution errors, specifically when clicking the non-existent sprite of a deleted button.
That's something we can't look at unless we see the code regarding that. How can you click something not existing? Any chance you're just missing a check or not cleaning up things properly?
I solved this by double checking the index I was giving to the elements on insertion. Thanks and sorry for such a stupid mistake!

Overloading == and !=

I was on here earlier to get some information on overloading *= and found it very helpful.
I am now trying to overload == and !=. But I want to make the operator functions non-member functions.
Try not to hate all my code blocks - I have included what I believe to be relevant to the issues.
In my source code, I declare the functions:
bool operator==(const Statistician&, const Statistician&);
// checks whether Stat1 == Stat2
bool operator!=(const Statistician&, const Statistician&);
// checks whether Stat1 != Stat2
Later on I define the functions:
// Check if equal
bool operator==(const Statistician& Stat1, const Statistician& Stat2)
{
if ((Stat1.get_length() == Stat2.get_length()) &&
(Stat1.get_sum() == Stat2.get_sum()) &&
(Stat1.get_mean() == Stat2.get_mean()) &&
(Stat1.get_minimum() == Stat2.get_minimum()) &&
(Stat1.get_maximum() == Stat2.get_maximum()))
return true;
else
return false;
}
// Check if not equal
bool operator!=(const Statistician& Stat1, const Statistician& Stat2)
{
if ((Stat1.get_length() != Stat2.get_length()) &&
(Stat1.get_sum() != Stat2.get_sum()) &&
(Stat1.get_mean() != Stat2.get_mean()) &&
(Stat1.get_minimum() != Stat2.get_minimum()) &&
(Stat1.get_maximum() != Stat2.get_maximum()))
return true;
else
return false;
}
In my test driver, I do the actual testing:
if (Stat1 == Stat2) { cout << "Equal"; }
if (Stat1 != Stat2) { cout << "Not Equal"; }
The rest of my code works fine, and these are again not class member functions.
But when I compile I get these errors:
error C2678: binary '==' : no operator found which takes a left-hand operand of type 'Statistician' (or there is no acceptable conversion)
c:\program files (x86)\microsoft visual studio 11.0\vc\include\exception(507): could be 'bool std::operator ==(const std::exception_ptr &,const std::exception_ptr &)'
c:\program files (x86)\microsoft visual studio 11.0\vc\include\exception(512): or 'bool std::operator ==(std::nullptr_t,const std::exception_ptr &)'
c:\program files (x86)\microsoft visual studio 11.0\vc\include\exception(517): or 'bool std::operator ==(const std::exception_ptr &,std::nullptr_t)'
c:\program files (x86)\microsoft visual studio 11.0\vc\include\system_error(426): or 'bool std::operator ==(const std::error_code &,const std::error_condition &) throw()'
c:\program files (x86)\microsoft visual studio 11.0\vc\include\system_error(434): or 'bool std::operator ==(const std::error_condition &,const std::error_code &) throw()'
while trying to match the argument list '(Statistician, Statistician)'
error C2678: binary '!=' : no operator found which takes a left-hand operand of type 'Statistician' (or there is no acceptable conversion)
c:\program files (x86)\microsoft visual studio 11.0\vc\include\exception(522): could be 'bool std::operator !=(const std::exception_ptr &,const std::exception_ptr &)'
c:\program files (x86)\microsoft visual studio 11.0\vc\include\exception(527): or 'bool std::operator !=(std::nullptr_t,const std::exception_ptr &)'
c:\program files (x86)\microsoft visual studio 11.0\vc\include\exception(532): or 'bool std::operator !=(const std::exception_ptr &,std::nullptr_t)'
c:\program files (x86)\microsoft visual studio 11.0\vc\include\system_error(443): or 'bool std::operator !=(const std::error_code &,const std::error_condition &) throw()'
c:\program files (x86)\microsoft visual studio 11.0\vc\include\system_error(450): or 'bool std::operator !=(const std::error_condition &,const std::error_code &) throw()'
while trying to match the argument list '(Statistician, Statistician)'
After much internet research I still don't know what those errors mean.
First of all, your operator!= is wrong, it should be
if ((Stat1.get_length() != Stat2.get_length()) ||
(Stat1.get_sum() != Stat2.get_sum()) ||
(Stat1.get_mean() != Stat2.get_mean()) ||
(Stat1.get_minimum() != Stat2.get_minimum()) ||
(Stat1.get_maximum() != Stat2.get_maximum()))
return true;
else
return false;
(note || instead of &&). Better yet, make that
return !(Stat1==Stat2);
Now for the error you see: It looks like you forgot to include the header which declares these operators in the translation unit where you are using them. Or, if that is not the case, you need to check which namespaces they are in and if they can be found there from where they are called.
Just to check: If you say "In my source code, I declare the functions:" you mean the header-file (*.h) and with "later on" you mean the implementation file (*.cc), right?

using the boost::scoped_lock(Mutex &mx, bool initially_locked) constructor gives me errors

Isn't there a boost::scoped_lock constructor that takes a boolean as the second parameter? I thought I had used it before.
boost::scoped_lock(Mutex &mx, bool initially_locked)
The documentation for scoped_lock shows the second parameters as "unspecified". Anyone know what in the #(*$ that is suppose to mean?!?
the errors I get are:
c:\program files\boost\boost_1_39\boost\thread\win32\basic_timed_mutex.hpp(118) : error C2679: binary '+' : no operator found which takes a right-hand operand of type 'const bool' (or there is no acceptable conversion)
c:\program files\boost\boost_1_39\boost\date_time\posix_time\date_duration_operators.hpp(31): could be 'boost::posix_time::ptime boost::posix_time::operator +(const boost::posix_time::ptime &,const boost::gregorian::months &)' [found using argument-dependent lookup]
c:\program files\boost\boost_1_39\boost\date_time\date_duration_types.hpp(132): or 'boost::gregorian::date boost::date_time::months_duration<base_config>::operator +(const boost::gregorian::date &,const boost::date_time::months_duration<base_config> &)' [found using argument-dependent lookup]
with
[
base_config=boost::gregorian::greg_durations_config
]
c:\program files\boost\boost_1_39\boost\date_time\posix_time\date_duration_operators.hpp(75): or 'boost::posix_time::ptime boost::posix_time::operator +(const boost::posix_time::ptime &,const boost::gregorian::years &)' [found using argument-dependent lookup]
c:\program files\boost\boost_1_39\boost\date_time\date_duration_types.hpp(244): or 'boost::gregorian::date boost::date_time::years_duration<base_config>::operator +(const boost::gregorian::date &,const boost::date_time::years_duration<base_config> &)' [found using argument-dependent lookup]
with
[
base_config=boost::gregorian::greg_durations_config
]
c:\program files\boost\boost_1_39\boost\date_time\time.hpp(139): or 'boost::posix_time::ptime boost::date_time::base_time<T,time_system>::operator +(const boost::gregorian::date_duration &) const'
with
[
T=boost::posix_time::ptime,
time_system=boost::posix_time::posix_time_system
]
c:\program files\boost\boost_1_39\boost\date_time\time.hpp(159): or 'boost::posix_time::ptime boost::date_time::base_time<T,time_system>::operator +(const boost::posix_time::time_duration &) const'
with
[
T=boost::posix_time::ptime,
time_system=boost::posix_time::posix_time_system
]
while trying to match the argument list '(boost::system_time, const bool)'
c:\program files\boost\boost_1_39\boost\thread\locks.hpp(353) : see reference to function template instantiation 'bool boost::detail::basic_timed_mutex::timed_lock<TimeDuration>(const Duration &)' being compiled
with
[
TimeDuration=bool,
Duration=bool
]
c:\program files\boost\boost_1_39\boost\thread\locks.hpp(241) : see reference to function template instantiation 'bool boost::unique_lock<Mutex>::timed_lock<TimeDuration>(const TimeDuration &)' being compiled
with
[
Mutex=boost::mutex,
TimeDuration=bool
]
d:\imagehawk\projects\virtualpc_archiveservice\ifl\src\archiveservice\archive.cpp(599) : see reference to function template instantiation 'boost::unique_lock<Mutex>::unique_lock<bool>(Mutex &,const TimeDuration &)' being compiled
with
[
Mutex=boost::mutex,
TimeDuration=bool
]
Here's a bit of my source code if it helps:
void SpawnXMessageThread(bool bTakeLock=true) {
boost::mutex::scoped_lock lock(m_mtx,bTakeLock);
m_pxmessage= new XMessage();
m_pThread = new boost::thread(boost::ref(*m_pxmessage));
}
The idea is that I'll lock the m_mtx based on the boolean. This way if I lock m_mtx before calling SpawnXMessageThread I can tell SpawnXMessageThread not to lock the mutex (because I've aready locked it).
btw, I'm kinda new to boost and threads.
According to the docs, you can't do it directly. But you can do something like this:
boost::unique_lock lck(m_mtx, boost::defer_lock);
if(bTakeLock) lck.lock();