I have the following snippet:
typedef char OR[12];
class COR
{
OR m_or;
public:
COR(const char* or) { strcpy(m_or, or); }
COR(const COR& o) { strcpy(m_or, o.m_or); }
const char* GetOR() const { return m_or; }
#if 0 // I do not wish to use this as it will create a temporary object
bool operator<(const COR& left, const COR& right) const
{ return (strcmp(left.m_or, right.m_or) < 0); }
#endif
};
namespace std {
template<>
struct less<COR> {
bool operator()(const COR& cor, const char* or) const
{ return (strcmp(cor.GetOR(), or) < 0); }
};
}
When I try this I get an error:
error: no matching function for call to std::map<COR, SomeStruct*, std::less<COR>, std::allocator<std::pair<const COR, SomeStruct*> > >::find(const char*&)
I do not want to use any method that involves comparison of two "COR" objects. I will have comparison of COR with const char*. Can you guys suggest a way to do it?
Several methods:
Note: None of these generate extra copies as the values are always passed by reference (and since we don't normally mutate an object on comparison pass by const reference).
Method 1:
class COR
{
public:
// 1: Make it a member function
// Thus you only specify the right hand side.
// The left is implicit.
bool operator<(COR const& right) const
{
return (strcmp(m_or, right.m_or) < 0);
}
};
method 2:
class COR
{
public:
// 2: Make it a friend non member function
// Note: Just because I declare it here does not make it part of the class.
// This is a separate non member function
// The compiler makes the destinction because of the `friened`
friend bool operator<(COR const& left, COR const& right)
{
return (strcmp(left.m_or, right.m_or) < 0);
}
};
Method 3:
class COR
{
public:
// Just an example. Just need some way for the functor to access members
// In a way that will allow a strict weak ordering.
bool test(COR const& right) const {return (strcmp(m_or, right.m_or) < 0);}
};
// Define a functor.
// This is just a class with the operator() overloaded so that it can
// act like a function. You can make it do whatever you like but for
// comparisons it will be passed two members of the container (accept by const
// reference and make sure the functor is const member and things will go well).
struct CorTest
{
bool operator()(COR const& left, COR const& right) const
{
return left.test(right);
}
};
// When you declare the set you just pass as the second template parameter.
// (or third if it is a map)
std::set<COR, CorTest> mySet;
std::map<COR, int, CorTest> myMap;
The method you use will depend on situation.
In most situations I would use method (1). If there is a special sort order I needed for a one off event that I want to use with a sorted container then I would use method (3). method (2) can be used as an alternative to method (1) and in some situations is better (but you need to provide more details about usage before I would say use this).
You got this error because you made a mistake - the arguments type of the std::less operator() must be identical. So, this works:
template <>
struct std::less<COR>
{
bool operator()(const COR &a, const COR &b) const { return (strcmp(a.GetOR(), b.GetOR()) < 0); }
};
You're looking for the new overloaded versions of find(), lower_bound(), and upper_bound() added in C++14. They do exactly what you are asking for.
https://en.cppreference.com/w/cpp/container/set/find
Related
I wrote this C++17 code and expected it to work out of the box.
class putc_iterator : public boost::iterator_facade<
putc_iterator,
void,
std::output_iterator_tag
>
{
friend class boost::iterator_core_access;
struct proxy {
void operator= (char ch) { putc(ch, stdout); }
};
auto dereference() const { return proxy{}; }
void increment() {}
bool equal(const putc_iterator&) const { return false; }
};
I'm trying to match the behavior of all the standard OutputIterators by setting my iterator's member typedefs value_type and reference to void (since those types are meaningless for an iterator whose operator* doesn't return a reference).
However, Boost complains:
In file included from prog.cc:2:
/opt/wandbox/boost-1.63.0/clang-head/include/boost/iterator/iterator_facade.hpp:333:50: error: cannot form a reference to 'void'
static result_type apply(Reference const & x)
^
It looks like Boost is trying to hard-code the generated operator*'s signature as reference operator*() const. That is, boost::iterator_facade could deduce the proper return type of operator*() by simply passing along whatever was returned by dereference(); but for some reason it's just not playing along.
What's the solution? I can't pass proxy as a template parameter of the base class since proxy hasn't been defined yet. I could pull proxy out into a detail namespace:
namespace detail {
struct proxy {
void operator= (char ch) { putc(ch, stdout); }
};
}
class putc_iterator : public boost::iterator_facade<
putc_iterator,
void,
std::output_iterator_tag,
detail::proxy
>
{
friend class boost::iterator_core_access;
auto dereference() const { return detail::proxy{}; }
void increment() {}
bool equal(const putc_iterator&) const { return false; }
};
but that seems awkward and is definitely something that "shouldn't be necessary."
Is this a bug in iterator_facade? Is it a feature-not-a-bug? If the latter, then how am I supposed to use it to create OutputIterators?
Also, a minor nitpick: even my workaround with the detail namespace is "wrong" in the sense that it makes std::is_same_v<putc_iterator::reference, detail::proxy> when what I want (for parity with the standard iterators) is std::is_same_v<putc_iterator::reference, void>.
Boost Iterator Facade was good at the time, but now it is outdated as it is not very flexible (it doesn't play well with auto and with r-value references that in principle can be creating by dereferencing a r-value iterator). I am not againts the facade concept, but it could be upgraded to C++11.
In addition now with C++11 is easier to write iterator from scratch.
Anyway, if you need to define a reference just to comply with the arguments to be passed, (and if you promise not use it) you can use void* instead of void. (Or perhaps for consistency use proxy& and define it outside the class).
class putc_iterator : public boost::iterator_facade<
putc_iterator,
void*,
std::output_iterator_tag
>
{
friend class boost::iterator_core_access;
struct proxy {
void operator= (char ch) { putc(ch, stdout); }
};
auto dereference() const { return proxy{}; }
void increment() {}
bool equal(const putc_iterator&) const { return false; }
};
I have a class design similar to the following:
class MyClass {
public:
bool IsValid() const;
void MakeValid();
private:
bool CheckValidity(bool fix);
};
bool MyClass::IsValid() const {
// Check validity, but don't fix any problems found. Doesn't work.
return CheckValidity(false);
}
void MyClass::MakeValid() {
// Check validity and fix problems found.
CheckValidity(true);
}
IsValid should be const, because it doesn't make changes. MakeValid should be non-const, because it does make changes. They share the same implementation, CheckValidity, but because CheckValidity may or may not make changes, it can't be marked const.
What's the best way to handle this? The simplest approach is to just use const_cast, but casting away const feels a bit dirty:
bool MyClass::IsValid() const {
// Check validity, but don't fix any problems found.
return const_cast<MyClass*>(this)->CheckValidity(false);
}
Is this a legitimate use of const_cast? Is there a better approach?
I'm assuming your implementation looks similar to this:
bool CheckValidity(bool fix)
{
// Actually check validity.
bool isValid = ...;
if (!isValid && fix)
{
// Attempt to fix validity (and update isValid).
isValid = ...;
}
return isValid;
}
You really have two different functions shoved into one. One of the key indicators of this kind of entanglement is the boolean argument to the function... which smells because the caller cannot immediately discern whether to put true or false without referencing code/docs.
Split up the method:
bool CheckValidity() const
{
// Actually check validity.
bool isValid = ...;
return isValid;
}
void FixValidity()
{
// Attempt to fix validity.
// ...
}
And then your public methods can make the calls more appropriately.
bool IsValid() const
{
// No problem: const method calling const method
return CheckValidity();
}
void MakeValid()
{
if (!CheckValidity()) // No problem: non-const calling const
{
FixValidity(); // No problem: non-const calling non-const
}
}
Here is an approach that might be useful in some cases. It might be overkill for your particular situation.
Your CheckValidity function could be passed a handler object. The CheckValidity function would find what was not valid, and call an appropriate method of the handler object. You could have many different methods for different kinds of validity violations, and those methods could be passed enough information that the problem could be fixed if necessary. To implement IsValid, you just need to pass a handler which sets a flag indicating there was a problem. To implement MakeValid, you can pass a handler which actually fixes the problem. The const issue is addressed by having the fixing handler keep a non-const reference to the object.
Here is an example:
class MyClass {
public:
bool IsValid() const
{
bool flag = false;
CheckValidity(FlagProblems{flag});
return flag;
}
void MakeValid()
{
CheckValidity(FixProblems{*this});
}
private:
struct FlagProblems {
bool& flag;
void handleType1(arg1,arg2) const { flag = true; }
void handleType2(arg1,arg2,arg3) const { flag = true; }
.
.
.
};
struct FixProblems {
MyClass& object;
void handleType1(arg1,arg2) const { ... }
void handleType2(arg1,arg2,arg3) const { ... }
.
.
.
};
template <typename Handler>
bool CheckValidity(const Handler &handler) const
{
// for each possible problem:
// if it is a type-1 problem:
// handler.handleType1(arg1,arg2);
// if it is a type-2 problem:
// handler.handleType2(arg1,arg2,arg3);
// .
// .
// .
}
};
Using the template allows for maximum efficiency. Alternatively, using a base class with virtual functions for the handler might provide a smaller executable size.
If the ways in which the object can be invalid are simpler, then having CheckValidity return a struct containing the relevant information may be more straightforward.
You can use a template specialization to separate the parts that only have purpose on a non-const object.
Following is an implementation for a toy class. It has a single c-array member v with 10 ints, and, for our purposes, it is only valid when every single one of them equals to zero.
class ten_zeroes {
int v[10];
void fix(int pos) {v[pos] = 0;}
public:
ten_zeroes() { // construct as invalid object
for (int i=0;i<10;i++) {
v[i] = i;
}
}
};
See that I already made a function member that fixes an invalid position, and a nice constructor that initializes it as an invalid object(don't do that :D)
Since we are going to use templates, we need to move the implementation of the check/fix cycle outside of the class. In order for the relevant functions to be able to access v and the fix() method, we'll make them friends. Our code now looks like:
class ten_zeroes {
int v[10];
void fix(int pos) {v[pos] = 0;}
public:
ten_zeroes() { // construct as invalid object
for (int i=0;i<10;i++) {
v[i] = i;
}
}
template<typename T>
friend void fix(T& obj, int pos);
template<typename T>
friend bool check(T& obj);
};
check()'s implementation is straightforward:
// Check and maybe fix object
template<typename T>
bool check(T& obj){
bool result = true;
for(int i=0;i<10;i++) {
if (obj.v[i]) {
result = false;
fix(obj, i);
}
}
return result;
}
Now here is the tricky part. We want our fix() function to change behaviour based on constness. For that we'll need to specialize the template. For a non-const object, it will fix the position. For a const one, it will do nothing:
// For a regular object, fix the position
template<typename T>
void fix(T& obj, int pos) { obj.fix(pos);}
// For a const object, do nothing
template<typename T>
void fix(const T& obj, int pos) {}
Finally, we write our is_valid() and make_valid() methods, and here we have the full implementation:
#include <iostream>
class ten_zeroes {
int v[10];
void fix(int pos) {v[pos] = 0;}
public:
ten_zeroes() { // construct as invalid object
for (int i=0;i<10;i++) {
v[i] = i;
}
}
bool is_valid() const {return check(*this);} // since this is const, it will run check with a const ten_zeroes object
void make_valid() { check(*this);} // since this is non-const , it run check with a non-const ten_zeroes object
template<typename T>
friend void fix(T& obj, int pos);
template<typename T>
friend bool check(T& obj);
};
// For a regular object, fix the position
template<typename T>
void fix(T& obj, int pos) { obj.fix(pos);}
// For a const object, do nothing
template<typename T>
void fix(const T& obj, int pos) {}
// Check and maybe fix object
template<typename T>
bool check(T& obj){
bool result = true;
for(int i=0;i<10;i++) {
if (obj.v[i]) {
result = false;
fix(obj, i);
}
}
return result;
}
int main(){
ten_zeroes a;
std::cout << a.is_valid() << a.is_valid(); // twice to make sure the first one didn't make any changes
a.make_valid(); // fix the object
std::cout << a.is_valid() << std::endl; // check again
}
I hope you don't mind the main() function there. It will test our little toy, and output 001, as expected. Now any maintenance on this code will not have to deal with code duplication, what you probably was intending to avoid. I hope this was helpful.
Of course, if you intend to hide these implementation details from the final user, you should move them to an appropriate detail namespace. I'll leave that up to you :)
I'm working on some code and I have a section where I do a one off sort function. To implement it I decided it was easiest to overload the operator< function. What I would prefer to do is move the implementation of the sort closer to the actual call by using some sort of boost::bind, boost::phoenix, lambda or some other type of implementation. Unfortunately I don't have access to new C++11 functionality. Below is some example code.
// In a header
struct foo
{
char * a;
char * c_str() { return a; }
}
// In a header
struct bar
{
foo * X;
bar(foo * _X) : X(_X) {}
bool operator < (const bar& rhs) const
{
return std::string(X->c_str()) < std::string(rhs.X->c_str());
}
};
struct bars : public std::vector<bar> { ... some stuff };
// Some other header
bars Bs;
// A cpp file
... other stuff happens that fills the Xs vector with objects
...::Function()
{
// Current use and it works fine
std::sort(Bs.begin(), Bs.end())
// Would like something that accomplishes this:
// std::sort(Bs.begin(), Bs.end(),
// std::string(lhs.X->c_str()) < std::string(rhs.X->c_str()))
// A non-working example of what I'm trying to do
// std::sort(Xs.begin(), Xs.end(),
// std::string((bind(bar::X->c_str(), _1)) <
// std::string((bind(bar::X->c_str(), _2)) )
}
I get lost when trying to figure out how to access the member pointers, member function and then cast the result all within a boost::bind function.
Thank you for your help.
I'm sure you can twist your way out of this using ample helpings of
Boost Phoenix bind and lambda
Boost Bind protect
However, I've learned to avoid these situations. Edit In fact, see below for one such contraption. I find this very very error prone and hard to reason about.
What you're seeing is, in essence, a violation of the Law Of Demeter. If you "just" wrote the code (not in a lambda), already it would be handling too many tasks.
So the first thing I'd do is rethink the class design.
The second thing I'd do is /extract/ different responsibilities from your comparator. Notice, that the comparator does three things:
access the c_str() of the X in lhs
access the c_str() of the X in rhs
compare the two
The first two steps are clear candidates for extraction. Let's write the generic comparer that remains first:
template <typename F>
struct compare_by_impl {
compare_by_impl(F f = F{}) : _f(std::move(f)) {}
template <typename T, typename U>
bool operator()(T const& a, U const& b) const {
return _f(a) < _f(b);
}
private:
F _f;
};
As always, it's nice to have factory function that will deduce the accessor type (in case you can get away with just using Phoenix there, it will save you specifying the (arcane) typenames involved in the expression templates):
template <typename Accessor>
compare_by_impl<Accessor> comparer_by(Accessor&& f) {
return compare_by_impl<Accessor>(std::forward<Accessor>(f));
}
Now you could already move the implementation with your sort call:
void Function()
{
struct accessX_c_str {
std::string operator()(bar const& b) const {
return b.X->c_str();
}
};
std::sort(Bs.begin(), Bs.end(), comparer_by(accessX_c_str()));
}
I'd personally leave it there.
Here's some more twisted contraptions:
// to avoid `comparer_by`
std::sort(Bs.begin(), Bs.end(), phx::bind(accessX_c_str(), arg1) < phx::bind(accessX_c_str(), arg2));
// to avoid any helper types (!?!?!? untested!)
std::sort(Bs.begin(), Bs.end(),
phx::construct<std::string>(phx::bind(&foo::c_str, phx::lambda [ phx::bind(&bar::X, arg1) ](arg1)))
< phx::construct<std::string>(phx::bind(&foo::c_str, phx::lambda [ phx::bind(&bar::X, arg1) ](arg2)))
);
This question already has answers here:
How can I use std::maps with user-defined types as key?
(8 answers)
Closed 9 years ago.
I am trying to create a set of objects. Merely defining the set is giving errors. I do not have a compiler right now with boost. So I used an online IDE. Here is the link to the code http://codepad.org/UsBAMmuh. Somehow, it does not seem to work. Eventually, I would like to pass a reference to this set in the constructor of another class.
#include <iostream>
#include <boost/optional.hpp>
#include <boost/ref.hpp>
#include <boost/serialization/vector.hpp>
using namespace std;
class Fruit {
};
class Env
{
public:
Env(std::set<Fruit>& apples);
std::set<Fruit>& GetApples() const;
void AddApple(Fruit const& fruit);
private:
std::set<Fruit>& _apples;
};
Env::Env(std::set<Fruit>& apples):
_apples(apples)
{
}
std::set<Fruit>& Env::GetApples() const
{
return _apples;
}
void Env::AddApple(Fruit const& fruit)
{
this->_apples.insert(fruit);
}
class EnvHolder{
public:
void SetEnv (Env const& env);
Env& GetEnv()const;
private:
boost::scoped_ptr<Env> _env;
};
void EnvHolder::SetEnv(Env const& env)
{
this->_env.reset(new Env(env));
}
Env& EnvHolder::GetEnv() const
{
return *this->_env;
}
int main() {
std::set<Fruit> fruits;
//Fruit *fr = new Fruit();
//fruits.insert(*fr);
//Env env(fruits);
cout << "Hello" << endl;
return 0;
}
I get the following error:
/usr/local/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_function.h: In member function 'bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = Fruit]':
/usr/local/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/boost_concept_check.h:358: instantiated from 'void __gnu_cxx::_BinaryFunctionConcept<_Func, _Return, _First, Second>::_constraints() [with _Func = std::less, _Return = bool, _First = Fruit, _Second = Fruit]'
/usr/local/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_set.h:112: instantiated from '__gnu_norm::set, std::allocator >'
/usr/local/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../include/c++/4.1.2/debug/set.h:45: instantiated from '__gnu_debug_def::set, std::allocator >'
t.cpp:35: instantiated from here
Line 226: error: no match for 'operator<' in '__x < __y'
compilation terminated due to -Wfatal-errors.
When you want to put objects of a class into an associative container, e.g., a std::set<T>, you'll need to provide some way to identify the objects in that container. The ordered associative containers (std::map<K, V>, std::set<T> and their "multi"-versions) use a strict weak ordering to to identify object. This means you either define a suitable less than operator or you provide a comparison type when defining the std::set<T>. For starters it is probably easiest to define a less than operator, e.g.:
class Fruit {
std::string name_;
public:
Fruit(std::string const& name): name_(name) {}
std::string name() const { return this->name_; }
};
bool operator< (Fruit const& f0, Fruit const& f1) {
return f0.name() < f1.name();
}
bool operator> (Fruit const& f0, Fruit const& f1) { return (f1 < f0); }
bool operator<= (Fruit const& f0, Fruit const& f1) { return !(f1 < f0); }
bool operator>= (Fruit const& f0, Fruit const& f1) { return !(f0 < f1); }
Although adding these operators will make your code compile, it probably won't make it work too well: since the Fruit class has no members, there is no way to distinguish them. Hence, all Fruit objects are considered to be the in the same equivalence class. For an actual Fruit class you would have some members and you would order your objects according to them.
Although strictly speaking only operator<() is needed, it is reasonable to provide the other relation operators, too. They always look the same, though, i.e., they simply delegate to operator<(). Aside from choosing to implement full set of relation operators, the code also chooses to implement the comparison operators as non-member functions: the operators could also be implemented as member function. However, if there are implicit conversion involved, the member operators behave asymmetric: the allow conversions on the right hand side operand but not on the left hand side operand. The non-member implementation make the conversion behavior symmetrical.
Using a comparison type would look something like this:
struct FruitCmp {
bool operator()(Fruit const& f0, Fruit const& f1) const {
return f0.name() < f1.name();
}
};
std::set<Fruit, FruitCmp> setOfFruit;
Of course, in all these case where false is return the proper logic implementing a strict weak ordering need to go. Typically, the easiest approach is to define the comparison in terms of a lexicographical comparison of the key members.
How do I make a class in C++, when initialized, return a Boolean value when its name is invoked, but no explicit function call make, like ifstream. I want to be able to do this:
objdef anobj();
if(anobj){
//initialize check is true
}else{
//cannot use object right now
}
not just for initialization, but a check for its ability to be used.
The way istream does it is by providing an implicit conversion to void*
http://www.cplusplus.com/reference/iostream/ios/operator_voidpt/
stream output and implicit void* cast operator function invocation
Update In reaction to the comments, the Safe Bool Idiom would be a far better solution to this: (code directly taken from that page)
class Testable {
bool ok_;
typedef void (Testable::*bool_type)() const;
void this_type_does_not_support_comparisons() const {}
public:
explicit Testable(bool b=true):ok_(b) {}
operator bool_type() const {
return ok_==true ?
&Testable::this_type_does_not_support_comparisons : 0;
}
};
template <typename T>
bool operator!=(const Testable& lhs,const T& rhs) {
lhs.this_type_does_not_support_comparisons();
return false;
}
template <typename T>
bool operator==(const Testable& lhs,const T& rhs) {
lhs.this_type_does_not_support_comparisons();
return false;
}
The article by Bjorn Karlsson contains a reusable implementation for the Safe Bool Idiom
Old sample:
For enjoyment, I still show the straight forward implementation with operator void* overloading, for clarity and also to show the problem with that:
#include <iostream>
struct myclass
{
bool m_isOk;
myclass() : m_isOk(true) { }
operator void* () const { return (void*) (m_isOk? 0x1 : 0x0); }
};
myclass instance;
int main()
{
if (instance)
std::cout << "Ok" << std::endl;
// the trouble with this:
delete instance; // no compile error !
return 0;
}
This is best accomplished using the safe bool idiom.
You provide an implicit conversion to a member-function-pointer, which allows instances of the type to be used in conditions but not implicitly convertyed to bool.
You need a (default) constructor and an operator bool()().
class X {
public:
operator bool ()const{
//... return a boolean expression
}
};
usage:
X x; // note: no brackets!
if( x ) {
....
}
You'll want to create an operator bool function (or as boost does, an unspecified_bool_type that has certain improved properties I can't recall offhand). You may also want to create operator! (For some reason I seem to recall iostreams do this too).