I am using an external C++ library that lacks const-correctness. Lets say I am working with objects of the following class:
// Library.h
namespace Library {
class Message {
public:
std::string getData() {
return data_;
}
private:
std::string data_;
};
} // namespace Library
Note that getData() returns a copy, thus a call to the method does not change the Message object and it should be const. However, the vendor decided it's not.
On my side of the code, const-correctness is important and the Message is to be used in a function like so:
// MyApplication.cpp
template<class T>
void handleMessage(const T& msg) {
std::string content = msg.getData();
// interprete and process content ...
}
Is there a way to achieve this? In other words, how to work around the error: passing 'const Library::Message' as 'this' argument discards qualifiers error without changing the signature of the handleMessage function?
You could also use wrapper with mutable member variable like:
#include <string>
class Message {
public:
std::string getData() {
return data_;
}
Message(std::string data): data_{data} { }
private:
std::string data_;
};
class MessageWrapper {
public:
MessageWrapper(Message message): message{message} {}
std::string getData() const {
return message.getData();
}
private:
mutable Message message;
};
template<class T>
void handleMessage(const T& msg) {
std::string content = msg.getData();
}
int main() {
MessageWrapper mw{{"abc"}};
handleMessage(mw);
}
[live demo]
Edit:
To force const correctness you could save once retrieved data from the message e.g.:
#include <string>
#include <optional>
class Message {
public:
std::string getData() {
return data_;
}
Message(std::string data): data_{data} { }
private:
std::string data_;
};
class MessageWrapper {
public:
MessageWrapper(Message message): message{message} {}
std::string getData() const {
return (data)?(*data):(*(data = message.getData()));
}
private:
mutable Message message;
mutable std::optional<std::string> data;
};
template<class T>
void handleMessage(const T& msg) {
std::string content = msg.getData();
}
int main() {
MessageWrapper mw{{"abc"}};
handleMessage(mw);
}
[live demo]
You basically have two options. You could use a const_cast
template<class T>
void handleMessage(const T& msg) {
std::string content = const_cast<T&>(msg).getData();
// interprete and process content ...
}
this is fine as long as you know for sure that getData really does not modify any members. Or if you dont mind some overhead you can make a copy:
template<class T>
void handleMessage(const T& msg) {
T copy = msg;
std::string content = copy.getData();
// interprete and process content ...
}
... or as a third option, if you want to hide the const_cast from the call site you can wrap it:
class MyMessage {
Message msg;
public:
std::string getData() const {
return const_cast<Message>(msg).getData();
}
};
Related
I have the generic class which can store a value and a type of the value encoded as a string.
#include <iostream>
#include <string>
#include <memory>
#include <cassert>
struct IValueHolder
{
virtual ~IValueHolder() = default;
virtual const std::string& getType() = 0;
virtual void setType(const std::string& t_type) = 0;
};
template<class T>
class ValueHolder : public IValueHolder
{
private:
T m_value;
std::string m_type;
public:
ValueHolder(T t_value) : m_value(t_value){}
virtual const std::string& getType() override
{
return m_type;
}
virtual void setType(const std::string& t_type) override
{
m_type= t_type;
}
const T& getValue() const
{
return m_value;
}
};
std::unique_ptr<IValueHolder> build_int_property()
{
auto p32{ std::make_unique<ValueHolder<int32_t>>(0) };
p32->setType("int32");
return std::move(p32);
}
int main()
{
auto v32 = dynamic_cast<ValueHolder<int32_t>*>(build_int_property().get());
assert(v32->getValue() == 0); // FAILS
assert(v32->getType() == "int32"); // FAILS
return EXIT_SUCCESS;
}
And I have another utility function build_int_property which builds an integer property. But unfortunately, the tests fail. Can anyone explain what is going wrong here?
If I have a class defined as follows in C++
class sample
{
private:
int data;
public:
sample()
{
data=0;
}
int get_data()
{
return data;
}
void set_data(int data)
{
this->data = data;
}
};
and I want to expose it to cython code using:
cdef extern from "sample.cpp":
cdef cppclass sample:
sample() except +
int get_data()
void set_data(int n)
Is there a way to expose the getter and setter in that class in such a way that they can then be used in cython using syntax such as:
a = obj.data
instead of
a = obj.get_data()
I know it is possible to do that by wrapping the class in cython defined class, but I would like to avoid that avoid that overhead.
Maybe I am asking for too much.
Disclaimer: I don't know cython, so I cannot say if the following will be fine for cython. However, my strategy would be to implement access via s.data already in the C++ code to keep the bindings slim and straightforward.
C++ has no attributes, but one can emulate them:
#include <iostream>
template <typename T,typename M,M (T::*getter)(),void (T::*setter)(M)>
struct Attribute {
T* parent;
Attribute(T* parent) : parent(parent){}
operator M() const {
return (parent->*getter)();
}
void operator=(const M& m){
(parent->*setter)(m);
}
};
class sample
{
private:
int data_;
public:
sample()
{
data_=0;
}
int get_data()
{
return data_;
}
void set_data(int data_)
{
this->data_ = data_;
}
Attribute<sample,int,&sample::get_data,&sample::set_data> data{this};
};
int main() {
sample s;
s.data = 42;
std::cout << s.data;
}
Output is 42. Note that I had to assume a int parameter for the setter. To enable also const int& a bit more will be needed.
Using the definition of the sample c++ class in the accepted response above by #idclev 463035818, and copied here for convenience:
#include <iostream>
template <typename T,typename M,M (T::*getter)(),void (T::*setter)(M)>
struct Attribute {
T* parent;
Attribute(T* parent) : parent(parent){}
operator M() const {
return (parent->*getter)();
}
void operator=(const M& m){
(parent->*setter)(m);
}
};
class sample
{
private:
int data_;
public:
sample()
{
data_=0;
}
int get_data()
{
return data_;
}
void set_data(int data_)
{
this->data_ = data_;
}
Attribute<sample,int,&sample::get_data,&sample::set_data> data{this};
};
I tested declaring that C++ class in cython with a flat public property, and ... it works! This does the job.
cdef extern from "sample.cpp":
cdef cppclass sample:
sample() except +
int data
Testing that and instrumenting the accessors in the example shows that the accessors are properly called.
Many thanks to everyone! That was very helpful.
Suppose I have a class in C++11 like this:
class Something
{
...
private:
class1* a;
class2* b;
class3* c;
public:
class1* reada() { return a; }
class2* readb() { return b; }
class3* readc() { return c; }
void customFunctionForclass1();
void customFunctionForclass2();
void customFunctionForclass3();
}
}
I'd like to make the read functions templated so that if another programmer adds another member class, the corresponding read function will be template-magic created.
Something like this maybe?
class Something
{
...
private:
templateContainer = {class1*,class2*,class3*}
template<thing in templateContainer>
thing variableOfTypeThing;
public:
template<thing in templateContainer>
<thing> read() {return variableOfTypeThing<thing>;}
void customFunctionForclass1();
void customFunctionForclass2();
void customFunctionForclass3();
}
As you can tell from the example, I'm confused.
Basically, I have a class which acts as a container for guaranteed unique class variables (no class1 A; class1 B)
Some function groups for the class are almost identical some function groups are highly varied. It would be great for future people to only have to modify the different parts of the class and get the rest from the templates.
I thought maybe there would be a way by splitting this class up into lots of classes and stuffing them into an array of void pointers, but that seems unwise.
Suggestions?
I'd like to make the read functions templated so that if another programmer adds another member class, the corresponding read function will be template-magic created.
You could encapsulate the user defined classes in a thin wrapper class with a read() function that returns the contained instance. Adding a user defined class to Something would then be done by inheriting wrapper<user_defined_class>.
Basically, I have a class which acts as a container for guaranteed unique class variables
Inheriting this wrapper prevents you from including the same class twice so it could possibly be a way forward:
#include <iostream>
// the "thing" wrapper
template<typename T>
struct thing {
// forward construction arguments to the contained variable
template<class... Args>
thing(Args&&... args) : variable(std::forward<Args>(args)...) {}
// basic interface, const and non-const. I called it get() instead of read()
T const& get() const { return variable; }
T& get() { return variable; }
private:
T variable;
};
// a troublesome user defined class that is not default constructibe :-(
struct user_defined {
user_defined() = delete; // silly example really, but it's just to demonstrate
user_defined(const std::string& v) : str(v) {}
user_defined& operator=(const std::string& v) {
str = v;
return *this;
}
std::string const& say() const { return str; }
private:
std::string str;
};
std::ostream& operator<<(std::ostream& os, const user_defined& ud) {
return os << ud.say();
}
// ... and the "Something" class that inherits the wrapped types.
class Something : thing<int>,
thing<double>,
thing<user_defined>
{
public:
// add initial values for types that are not default constructible
Something(const std::string& val) : thing<user_defined>(val) {}
Something() : Something("") {} // default ctor
// access via derived class, const and non-const
template<typename T>
T const& get() const {
return thing<T>::get(); // get() from the correct base
}
template<typename T>
T& get() {
return thing<T>::get(); // get() from the correct base
}
};
void print(const Something& s) {
// using the const interface
std::cout << s.get<int>() << "\n";
std::cout << s.get<double>() << "\n";
std::cout << s.get<user_defined>() << "\n";
}
int main() {
Something foo;
// using the non-const interface to set
foo.get<int>() = 10;
foo.get<double>() = 3.14159;
foo.get<user_defined>() = "Hello world";
print(foo);
}
Edit: It doesn't fulfill the index part of your question though. You access it using the type you'd like to get() as a tag. You basically build a very rudimentary tuple I guess.
Code based on #Ted Lyngmo's answer:
#include <iostream>
#include <string>
template<typename T>
struct thing {
// forward construction arguments to the contained variable
template<class... Args>
thing(Args&&... args) : variable(std::forward<Args>(args)...) {}
// basic interface, const and non-const. I called it get() instead of read()
T const& get() const { return variable; }
T& get() { return variable; }
protected:
T variable;
};
template<typename ...Ts>
struct things : thing<Ts>... {
template<class... SubTs>
things(thing<SubTs>&&... ts) : thing<SubTs>(std::move(ts))... {}
// access via derived class, const and non-const
template<typename T>
T const& get() const {
return thing<T>::get(); // get() from the correct base
}
template<typename T>
T& get() {
return thing<T>::get(); // get() from the correct base
}
};
// a troublesome user defined class that is not default constructibe :-(
struct user_defined {
user_defined() = delete; // silly example really, but it's just to demonstrate
user_defined(const std::string& v) : str(v) {}
user_defined& operator=(const std::string& v) {
str = v;
return *this;
}
std::string const& say() const { return str; }
private:
std::string str;
};
struct non_default {
non_default() = delete;
non_default(int) {}
};
std::ostream& operator<<(std::ostream& os, const user_defined& ud) {
return os << ud.say();
}
// ... and the "Something" class that inherits the wrapped types.
class Something : public things<int, double, user_defined, non_default>
{
public:
// add initial values for types that are not default constructible
Something(const std::string& val) : things(thing<user_defined>(val), thing<non_default>(0)) {}
Something() : Something("") {} // default ctor
};
void print(const Something& s) {
// using the const interface
std::cout << s.get<int>() << "\n";
std::cout << s.get<double>() << "\n";
std::cout << s.get<user_defined>() << "\n";
}
int main() {
Something foo;
// using the non-const interface to set
foo.get<int>() = 10;
foo.get<double>() = 3.14159;
foo.get<user_defined>() = "Hello world";
print(foo);
}
I am trying to create template classes for some repetitive functions that will be required for sending data around, of different types. However, my issue (I think) is really with InterfacePublisher::addSubscription() function that is utilizing boost::signals2::signal::connect().
It seems like connect function is taking the location of the base classes, even though derived classes override them. I am sure there is going to be a fix for this but am stuck with it for a long while now.
I am pasting my code below. The idea is to pass a string from StringPublisher to StringSubscriber without hard-coding the class names through the templates:
#include <string>
#include <iostream>
#include <boost/lambda/lambda.hpp>
#include <boost/signals2/signal.hpp>
#include <boost/signals2/signal_base.hpp>
#include <boost/signals2/slot.hpp>
#include <boost/signals2/slot_base.hpp>
template <class T>
class InterfaceSubscriber
{
public:
InterfaceSubscriber(const std::string& name)
: mName (name) {}
virtual void onData (const std::string& source, T& data)
{
std::cout << "InterfaceSubscriber::onData::BASE SHOULD BE IGNORED\n";
}
protected:
const std::string mName;
};
template <class T>
class InterfacePublisher
{
public:
InterfacePublisher(const std::string& publisherName)
: mPublisherName (publisherName)
{
}
void publish(T& data)
{
mSignalArgs(mPublisherName, data);
}
void addSubscription (InterfaceSubscriber<T>* subsc)
{
// The section where I think problem is. There is where the solution should be
mSignalArgs.connect( std::bind (InterfaceSubscriber<T>::onData , *subsc, std::placeholders::_1, std::placeholders::_2) );
}
protected:
boost::signals2::signal<void (const std::string& publisherName, T& data)> mSignalArgs;
const std::string mPublisherName;
};
class StringSubscriber : public InterfaceSubscriber<std::string>
{
public:
StringSubscriber (const std::string& subscName) : InterfaceSubscriber(subscName) {}
void onData (const std::string& source, std::string& data) override
{
std::cout << mName << ":[" << source << "]Received string of value: " << data << std::endl;
}
};
class StringPublisher : public InterfacePublisher<std::string>
{
public:
StringPublisher (const std::string& name) : InterfacePublisher(name) {}
};
int main()
{
StringSubscriber subscriber1("String_Subscriber_1");
StringSubscriber subscriber2("String_Subscriber_2");
StringPublisher publisher("Publisher_Of_String");
publisher.addSubscription(&subscriber1);
publisher.addSubscription(&subscriber2);
std::string str = "Hello World";
// This should lead to StringSubscriber::onData being called, but instead ends up calling InterfaceSubscriber<T>::onData
publisher.publish(str);
}
StringSubscriber is being sliced during the construction of the std::bind functor, resulting in InterfaceSubscriber<T>::onData() executing on an object with a runtime type of InterfaceSubscriber<T> rather than the runtime type of the object provided to InterfacePublisher<T>::addSubscription().
void addSubscription(InterfaceSubscriber<T>* subsc)
{
mSignalArgs.connect(std::bind(&InterfaceSubscriber<T>::onData,
*subsc, ...);
// ^~~ sliced
}
To resolve this, either pass the pointer directly or pass a std::ref object as the instance.
void addSubscription(InterfaceSubscriber<T>* subsc)
{
mSignalArgs.connect(std::bind(&InterfaceSubscriber<T>::onData,
subsc, ...);
// ^~~ pointer
}
or
void addSubscription(InterfaceSubscriber<T>* subsc)
{
mSignalArgs.connect(std::bind(&InterfaceSubscriber<T>::onData,
std::ref(*subsc), ...);
// ^~~ reference
}
I often want to define new 'Exception' classes, but need to have an appropriate constructor defined because constructors aren't inherited.
class MyException : public Exception
{
public:
MyException (const UString Msg) : Exception(Msg)
{
};
}
Typedefs don't work for this, because they are simply aliases, not new classes. Currently, to avoid repeating this trivial boilerplate, I use a #define which does the donkeywork.
#define TEXCEPTION(T) class T : public Exception \
{ \
public:\
T(const UString Msg) : Exception(Msg) {}; \
}
...
TEXCEPTION(MyException);
But I keep wondering if there's a better way of achieving this - maybe with templates, or some new C++0x feature
If you really want to have new classes derived from Exception, as opposed to having a template parameterized by a parameter, there is no way around writing your own constructor that just delegates the arguments without using a macro. C++0x will have the ability what you need by using something like
class MyException : public Exception
{
public:
using Exception::Exception;
};
You can read about the details of that (seem to have quite a bit of extra rules) in 12.9 "Inheriting Constructors" in the latest draft of C++0x.
In the meantime, i would recommend a policy based design (made small text, because the OP accepted the above, and not this policy stuff):
// deriving from Impl first is crucial, so it's built first
// before Exception and its Ctor can be used.
template<typename Impl>
struct ExceptionT : Impl, Exception {
// taking a tuple with the arguments.
ExceptionT(arg_types const& t = arg_types())
:Exception(Impl::Ctor(t)) { }
// taking a string. plain old stuff
ExceptionT(std::string const& s):Exception(Impl::Ctor(s)) { }
};
struct ExceptionDefImpl {
typedef boost::tuple<> arg_types;
// user defined ctor args can be done using a tuple
std::string Ctor(arg_types const& s) {
return std::string();
}
std::string const& Ctor(std::string const& s) {
return s;
}
};
// will inherit Ctor modifier from DefImpl.
struct MemoryLost : ExceptionDefImpl {
typedef boost::tuple<int> arg_types;
std::string Ctor(arg_types const& s) {
std::ostringstream os;
os << "Only " << get<0>(s) << " bytes left!";
return os.str();
}
int getLeftBytes() const { return leftBytes; }
private:
int leftBytes;
};
struct StackOverflow : ExceptionDefImpl { };
// alias for the common exceptions
typedef ExceptionT<MemoryLost> MemoryLostError;
typedef ExceptionT<StackOverflow> StackOverflowError;
void throws_mem() {
throw MemoryLostError(boost::make_tuple(5));
}
void throws_stack() { throw StackOverflowError(); }
int main() {
try { throws_mem(); }
catch(MemoryListError &m) { std::cout << "Left: " << m.getLeftBytes(); }
catch(StackOverflowError &m) { std::cout << "Stackoverflow happened"; }
}
You could parameterize your template class with an integer:
#include <iostream>
#include <string>
using namespace std;
enum ExceptionId {
EXCEPTION_FOO,
EXCEPTION_BAR
};
class Exception {
string msg_;
public:
Exception(const string& msg) : msg_(msg) { }
void print() { cout << msg_ << endl; }
};
template <int T>
class TException : public Exception {
public:
TException(const string& msg) : Exception(msg) {};
};
void
foo()
{
throw TException<EXCEPTION_FOO>("foo");
}
void
bar()
{
throw TException<EXCEPTION_BAR>("bar");
}
int
main(int argc, char *argv[])
{
try {
foo();
} catch (TException<EXCEPTION_FOO>& e) {
e.print();
};
try {
bar();
} catch (TException<EXCEPTION_BAR>& e) {
e.print();
};
return 0;
}
Although, I don't see why you would favor this over using a single class with an internal enumeration that is set/read at runtime:
class TException {
public:
enum Type { FOO, BAR };
TException(Type type, const string& msg) : Exception(msg), type_(type) {}
Type type() const { return type_; }
private:
Type type_;
};
Then just switch on the type when you catch a TException...
// You could put this in a different scope so it doesn't clutter your namespaces.
template<struct S> // Make S different for different exceptions.
class NewException :
public Exception
{
public:
NewException(const UString Msg) :
Exception(Msg)
{
}
};
// Create some new exceptions
struct MyExceptionStruct; typedef NewException<MyExceptionStruct> MyException;
struct YourExceptionStruct; typedef NewException<YourExceptionStruct> YourException;
struct OurExceptionStruct; typedef NewException<OurExceptionStruct> OurException;
// Or use a helper macro (which kinda defeats the purpose =])
#define MAKE_EXCEPTION(name) struct name##Struct; typedef NewException<name##Struct> name;
MAKE_EXCEPTION(MyException);
MAKE_EXCEPTION(YourException);
MAKE_EXCEPTION(OurException);
// Now use 'em
throw new MyException(":(");