I've got a global function that copies relevant bits of one object (or type Source) to another (of type Target), like so:
template<typename Source , typename Target>
void partialCopy( Source& source , Target& target )
{
// perform copy
}
The problem I find with global functions is that, unlike member functions, it is not instantly clear when coding which of the two arguments is the source and which is the target. Therefore I would like to have a member function partialCopy() in every class like so:
struct Foo
{
template<typename T>
void partialCopy( T& target )
{
::partialCopy( *this , target );
}
};
The problem now is that the member function has to be copied to dozens of classes. Is this a tolerable case of copy and paste programming? I've considered putting partialCopy in a header file partialCopy.h and using the preprocessor include to 'inject' it into each class, like so:
struct Foo
{
#include "partialCopy.h"
};
Foo f;
Bar b;
f.partialCopy( b );
Although this works I've never seen it done anywhere and don't know if its unacceptable.
I've already tried putting the partialCopy member function in a common base class and inheriting it but this doesn't work because the this keyword would then refer to the base class and not the derived class.
Is there an even better alternative? Please advise.
Edit
John's suggestion(in a thread that's been deleted) that I perform a static_cast to the derived class in a CRTP base class works nicely. #John please post this an answer and I will mark it as such.
I am posting this as an answer, because in my opinion it's appropriate. Henrik commented first, though. (However, this was also my first thought :))
const-reference
Use const& (const-reference) for source parameter. That way it's easily distinguishable from the target.
The added benefit is that it will verify and ensure const-correctness of your partial-copy function.
rvalue-reference
You might also think about overloading it for Source&&. If there are some buffers that are copied directly, your function might take use of it.
I would suggest overloading the stream operators for this.
E.g.
template<typename Source , typename Target>
void partialCopy(Source& source, Target& target)
{
// perform copy
}
effectively becomes:
template<typename Source , typename Target>
void operator>>(const Source& source, Target& target)
{
// perform copy
}
(also note that the Source parameter is now a const&, for clarity.
So you could simply write
Foo f;
Bar b;
f >> b;
Makes it much clearer what the source and target objects are.
I'm a bit late with this answer, but I thought you might be interested in a solution using CRTP as a clean alternative to copy-paste programming:
The problem now is that the member function has to be copied to dozens of classes. Is this a tolerable case of copy and paste programming? I've considered putting partialCopy in a header file partialCopy.h and using the preprocessor include to 'inject' it into each class [...].
Instead of copying or #including the code, consider the following:
// common code:
<template typename T>
class PartialCopyImplementer
{
public:
template<typename D>
void partialCopy(D& destination)
{
// ::partialCopy( *this , target );
}
};
// concrete implementations
class Foo1 : public PartialCopyImplementer<Foo1> // CRTP implementation
{
// ...
};
// concrete implementations
class Foo2 : public PartialCopyImplementer<Foo2> // CRTP ensures Foo1 and Foo2
// do not have a common base
{
// ...
};
The cleanest way would probably just be to leave partialCopy as a free function an use it that way. There is nothing inherently wrong with that, for example all the function in the standard libraries <algorithm> header are free function that will be used with objects.
It is also not really much clearer which of foo.partialCopy(bar) is the source and which the destination. Does partialCopy copy from or to bar? Generally it is useful to look at the documentation / function declaration in such cases. If you have clear names for the parameters and make them const when appropriat,e it should be pretty clear which way the objects get copied.
What about:
template<class T>
struct from_impl
{
T const& from;
from_impl(T const& f)
: from(f)
{}
};
template<class T>
from_impl<T> from(T const& f) {
return from_impl(f);
}
template<class T>
struct to_impl
{
T& to;
to_impl(T& t)
: to(t)
{}
};
template<class T>
to_impl<T> to(T& t) {
return to_impl(t);
}
template<class T>
void to(T const&); // prevent using with non-const values
template<class Source,class Target>
void partial_copy(from_impl<Source> source, to_impl<Target> target)
{
// use source.from and target.to to perform copy
}
// usage:
T1 object1;
T2 object2;
partial_copy(from(object1),to(object2));
This makes very clear what you want to do. from_impl and to_impl work like a kind of reference and from and to work as factory functions for easy usage. You could also try to implement something like.
partial_copy.from(Source).to(Target);
partial_copy(Source)->_(Target);
But normaly this is a lot of writing. Simply put partial_copy in its own namespace to prevent name clashes, let users make their own overload for customisation and use const& for signaling what source and destination are.
Related
EDIT: just to clarify, I understand why this code does not work,and I'm not attempting to fix it, but to understand what are the dangers if this code could compile without the semantic error.
I have found that the following code will cause a static semantic error.
I know that it's because std::list is a template class and that means that std::list<foo*> is a different type than std::list<bar*>
My question is, if the compiler would allow this type of conversion from std::list<bar*> to std::list<foo*> in the second call to print_all , what could be the danger?
I have searched around the site but couldn't find examples to bad things that could happen.
I have also tried to think of such examples but I'm not sure that these are correct or accurate.
(for example if the compiler would allow this, could I add a foo* object into the bar list in print_all() because it was converted to list?).
#include <list>
using std::list;
class foo {
// ...
};
class bar : public foo {
// ...
};
static void print_all(list<foo*>& L) {
// ...
}
list<foo*> LF;
list<bar*> LB;
// ...
print_all(LF); // works fine
print_all(LB); // static semantic error
list<foo*> and list<bar*> are two completely different classes, with no connection between them, other than beeing generated from the same template std::list (template<class T, class Allocator = std::allocator<T>> class list;). As such there isn't a conversion between them, unless the author of the template std::list explicitly wrote a conversion between std::list<T, A> and std::list<U, A> when T is a base class of U. And that is not written.
One way to achieve what you want is by creating template function:
template <class T, class A>
void print_all(std::list<T*, A>& l)
Now, there are a few caveats to be aware of:
I see no reason why you would make that static member. I would make it free function, but I would put it in a namespace with foo and bar
If you want to restrict it's usage strictly to foo and its derived classes you can do it with sfinae:
template <class T, class A, class E = std::enable_if_t<std::is_base_of_v<foo, T>>>
auto print_all(std::list<T*, A>& l)
{
}
And finally you should consider turning this into idiomatic C++ way of printing, aka streams and add the operator<<(std::ostream&, const std::list<T*, A>&) along with operator<<(std::ostream, const foo&) and maybe a virtual print function on foo. Here is extra important to define them in the same namespace as foo and bar.
You cannot use one vector instead of other because are different classes, but you can convert one vector to other implicitely or explicitely, using transformation or copy/ move constructors and assignment operator. It can cost you additional performance ( and memory in case of copy) overhead, but can be a deal in your particular case.
I have written two different container classes, which have the same interface but use different member data and algorithms to operate on their members. I also have a template function that takes a container and does some useful calculation:
class Container1
{
// implementation here
};
class Container2
{
// implementation here
};
template<typename ContainerType>
void my_function(ContainerType const& container, /* other parameters */)
{
// ...
}
What bothers me is the fact that 'my_function' should only accept Container1 or Container2, but this is not expressed by the code, since ContainerType can be any type. The function is templated by container type since it does the same thing no matter what is the internal implemetation of container.
I am considering a variant where Container1 and Container2 would be full specializations of a template class. Then I could be more specific about the argument of my_function:
template<typename T>
class Container;
// Tags to mark different container types
struct ContainerType1 { };
struct ContainerType2 { };
template<>
class Container<ContainerType1>
{
// implementation
};
template<>
class Container<ContainerType2>
{
// implementation
};
template<typename T>
void my_function(Container<T> const& container, /* other parameters */)
{
}
In the first case, the compilation with a wrong template parameter will fail if 'ContainerType' does not have the interface required by my_function, which is not very informative. In the second case, I would also get a compiler error (failed template parameter deduction) if I supply anything else than Container<ContainerType1> or Container<ContainerType2>, but I like it better since it provides a hint about what kind of template parameter is expected.
What are you thoughts about this? Is it a good design idea or not? Do you think it is worth the change in the code? There are many other functions like my_function in the code and sometimes it is not obvious what kind of template parameters they expect. What are my other options to make my_function more specific? I am aware the existence of Boost Concept Check Library.
For the sake of argument, let's suppose that I don't want to solve the problem by using inheritance and virtual functions.
In case it is relevant to the discussion, the common interface of Container1 and Container2 is imposed by using CRTP. There might be more container classes in the future.
There are a few solutions to this kind of problem.
Your solution (implementing your types as a template specialization) is one, but one I don't particularly like.
Another is the CRTP:
template<typename T>
struct Container {
// optional, but I find it helpeful
T* self() { return static_cast<T*>(this); }
T const* self() const { return static_cast<T const*>(this); }
// common code between every implementation goes here. It accesses itself through self(), never this
};
class ContainerType1: public Container<ContainerType1> {
// more details
};
class ContainerType2: public Container<ContainerType2> {
// more details
};
that is the core of the CRTP.
Then:
template<typename T>
void my_function(Container<T> const& container_, /* other parameters */)
{
T const& container = *(container.self());
}
and bob is your uncle. As a bonus, this provides a place to put common code.
Another option is a tag traits class that marks the types you want to support, like iterator_traits.
template<typename T>
struct is_container : std::false_type {};
template<>
struct is_container<ContainerType1> : std::true_type {};
template<>
struct is_container<ContainerType2> : std::true_type {};
you can even do SFINAE style pattern matching to detect a base type (like how iterators work).
Now your method can test on is_container<T>::value, or do tag dispatching on is_container<T>{}.
I think your first version is do-able.
At the end of the day, you always have to choose the optimum approach. Second one may look like an overkill although it gets the point across.
If you Container classes will both have a common function (let's say Container1::hasPackage() or Container2::hasPackage() and you choose to call it within my_function then it straight away puts your point across that the eligibility to call it is that function itself. After going through many such projects you will start reading the templates in a reverse manner - starting from the template definition - to see what least properties are needed qualify a particular class.
Having said all this, perhaps your question was more suited for Code Review
One example I created on ideone was using your classes but adding a member variable name to them both which is expected by my_function. Of course there may be classes that will support name but the developer may also burn his fingers a few times to realize the idea behind the function.
Mixins and function templates are two different ways of providing a behavior to a wide set of types, as long as these types meet some requirements.
For example, let's assume that I want to write some code that allows me to save an object to a file, as long as this object provides a toString member function (this is a rather silly example, but bear with me). A first solution is to write a function template like the following:
template <typename T>
void toFile(T const & obj, std::string const & filename)
{
std::ofstream file(filename);
file << obj.toString() << '\n';
}
...
SomeClass o1;
toFile(o1, "foo.txt");
SomeOtherType o2;
toFile(o2, "bar.txt");
Another solution is to use a mixin, using CRTP:
template <typename Derived>
struct ToFile
{
void toFile(std::string const & filename) const
{
Derived * that = static_cast<Derived const *>(this);
std::ofstream file(filename);
file << that->toString() << '\n';
}
};
struct SomeClass : public ToFile<SomeClass>
{
void toString() const {...}
};
...
SomeClass o1;
o.toFile("foo.txt");
SomeOtherType o2;
o2.toFile("bar.txt");
What are the pros and cons of these two approaches? Is there a favored one, and if so, why?
The first approach is much more flexible, as it can be made to work with any type that provides any way to be converted to a std::string (this can be achieved using traits-classes) without the need to modify that type. Your second approach would always require modification of a type in order to add functionality.
Pro function templates: the coupling is looser. You don't need to derive from anything to get the functionality in a new class; in your example, you only implement the toString method and that's it. You can even use a limited form of duck typing, since the type of toString isn't specified.
Pro mixins: nothing, strictly; your requirement is for something that works with unrelated classes and mixins cause them to be become related.
Edit: Alright, due to the way the C++ type system works, the mixin solution will strictly produce unrelated classes. I'd go with the template function solution, though.
I would like to propose an alternative, often forgotten because it is a mix of duck-typing and interfaces, and very few languages propose this feat (note: very close to Go's take to interfaces actually).
// 1. Ask for a free function to exist:
void toString(std::string& buffer, SomeClass const& sc);
// 2. Create an interface that exposes this function
class ToString {
public:
virtual ~ToString() {}
virtual void toString(std::string& buffer) const = 0;
}; // class ToString
// 3. Create an adapter class (bit of magic)
template <typename T>
class ToStringT final: public ToString {
public:
ToStringT(T const& t): t(t) {}
virtual void toString(std::string& buffer) const override {
toString(buffer, t);
}
private:
T t; // note: for reference you need a reference wrapper
// I won't delve into this right now, suffice to say
// it's feasible and only require one template overload
// of toString.
}; // class ToStringT
// 4. Create an adapter maker
template <typename T>
ToStringT<T> toString(T const& t) { return std::move(ToStringT<T>(t)); }
And now ? Enjoy!
void print(ToString const& ts); // aka: the most important const
int main() {
SomeClass sc;
print(toString(sc));
};
The two stages is a bit heavyweight, however it gives an astonishing degree of functionality:
No hard-wiring data / interface (thanks to duck-typing)
Low-coupling (thanks to abstract classes)
And also easy integration:
You can write an "adapter" for an already existing interface, and migrate from an OO code base to a more agile one
You can write an "interface" for an already existing set of overloads, and migrate from a Generic code base to a more clustered one
Apart from the amount of boiler-plate, it's really amazing how you seamlessly pick advantages from both worlds.
A few thoughts I had while writing this question:
Arguments in favor of template functions:
A function can be overloaded, so third-party and built-in types can be handled.
Arguments in favor of mixins:
Homogeneous syntax: the added behavior is invoked like any other member functions. However, it is well known that the interface of a C++ class includes not only its public member functions but also the free functions that operates on instances of this type, so this is just an aesthetic improvement.
By adding a non-template base class to the mixins, we obtain an interface (in the Java/C# sense) that can be use to handle all objects providing the behavior. For example, if we make ToFile<T> inherits from FileWritable (declaring a pure virtual toFile member function), we can have a collection of FileWritable without having to resort to complicated heterogeneous data structures.
Regarding usage, I'd say that function templates are more idiomatic in C++.
In my C++ library I have a type boost::variant<A,B> and lots of algorithms getting this type as an input. Instead of member functions I have global functions on this type, like void f( boost::variant<A,B>& var ). I know that this can also be achieved with templates, but this is not suitable for my design.
I am very fine with this style of programming:
boost::variant<A, B> v;
f( v );
but some of the users of this library are not used to it, and since the Boost.Variant concept is hidden by a type definition, they feel like calling v.f().
To achieve this, I can think of two possibilities: 1) overriding from boost::variant and 2) re-implementing boost::variant and adding my own member functions. I am not sure whether these ideas are good or not. Can you give me some help with this please? Are there other possibilities?
Another possibility: Use aggregation. Then you do not directly expose the boost.variant to the users of the library, giving you way more freedom for future improvements, and may simplify some debugging tasks by a significant amount.
General Advice:
Aggregation is less tightly coupled than inheritance, therefore better by default, except you know a use-case where you explicitly want to pass your object instance to already existing functions only taking variants. And even than the base class should have been designed with inheritance in mind.
Example for Aggregation for Your Problem:
As far as I understand it, the free functions already exist, and take a variant. Just define a class with the sole data member of the variant, and provide public member functions which do nothing but invoke the already existing free functions with the member variant, like
class variant_wrapper {
boost::variant<A,B> m_variant;
public:
variant_wrapper(...) : m_variant(...) {} // whatever c_tor you need.
void f() { f(m_variant); }
};
Using this approach you abstract away the fact that you are using boost.variant for your implementation (which you already do through a typedef for the library's users), giving you the freedom of later changing that (for optimization or feature extensions or whatever), you can decide to make the values immutable, have a more simple approach to debug accesses to your algorithms, etc. etc..
The disadvantage with the aggregation is that you cannot just pass the wrapper to a static_visitor, but as your users shall not know that there is a variant, and you know to simply pass the member variable, I do not see a big issue here.
Final rant:
C++ is not Java. You need to fix the users of the library...
What you would like to have are C# extension methods; such things do not exist in C++. However, I would not reimplement/implementation-copy boost.variant (maintenance burden), and I would not inherit from it. Use aggregation where possible.
I'd derive from boost::variant. That should be fine so long as you dont add data members to the class, and don't add virtual functions. (You may be able to do some of those but things are a little more iffy I think). Anyway this seems to work OK for me.
#include "boost/variant.hpp"
#include <iostream>
template<typename T1, typename T2>
struct my_print : public boost::static_visitor<>
{
void operator()( T1 t1 ) const
{
std::cout<<"FIRST TYPE "<<t1<<std::endl;
}
void operator()( T2 t2 ) const
{
std::cout<<"SECOND TYPE "<<t2<<std::endl;
}
};
template<typename T1, typename T2>
class MyVariant : public boost::variant<T1,T2>
{
public:
void print()
{
boost::apply_visitor(my_print<T1,T2>(), *this );
}
template<typename T>
MyVariant<T1,T2>& operator=(const T& t)
{
boost::variant<T1,T2>::operator=(t);
return *this;
}
MyVariant(const T1& t) : boost::variant<T1,T2>(t)
{
}
MyVariant(const T2& t) : boost::variant<T1,T2>(t)
{
}
template<typename T>
explicit MyVariant(const T& t) : boost::variant<T1,T2>(t)
{
}
};
int main()
{
MyVariant<int,std::string> s=1;
s.print();
s=std::string("hello");
s.print();
MyVariant<int,std::string> v2 = s;
v2.print();
s=boost::variant<int,std::string>(3);
s.print();
}
I was reading this morning the book The Pragmatic Programmer Chapter 3 on Basic Tools every programmer should have and they mentioned Code Generation Tools.
They mentioned one Perl script for C++ programs which helped automate the process of implementing the get/set() member functions for private data members.
Does anyone know about such a script and where to find it? I've been unable to come up with the right google keywords to find it.
Although it doesn't directly answer your question, you may find that generated code is actually unnecessary for managing properties in C++. The following template code will allow you to declare and use properties conveniently:
// Declare your class containing a few properties
class my_class {
public:
property<int> x;
property<string> y;
...
};
...
my_class obj;
cout << obj.x(); // Get
obj.y("Hello, world!"); // Set
Here is the code:
// Utility template to choose the 2nd type if the 1st is void
template <typename T, typename U>
struct replace_void {
typedef T type;
};
template <typename T>
struct replace_void<void, T> {
typedef T type;
};
// Getter/setter template
template <typename T, typename D = void>
class property {
typedef typename replace_void<D, property>::type derived_type;
derived_type& derived() { return static_cast<derived_type&>(*this); }
public:
property() {} // May be safer to omit the default ctor
explicit property(T const& v) : _v(v) {}
property(property const& p) : _v(p._v) {}
property& operator=(property const& p) { _v = p._v; return *this; }
T operator()() const { return _v; } // Getter
void operator()(T const& v) { derived().check(v); _v = v; } // Setter
protected:
// Default no-op check (derive to override)
void check(T const& v) const { (void)v; //avoid unused variable warning}
private:
T _v;
};
check() is a function that tests whether the value being assigned is valid. You can override it in a subclass:
class nonnegative_int : public property<int, nonnegative_int> {
public:
// Have to redeclare all relevant ctors unfortunately :(
nonnegative_int(int v) : property<int, nonnegative_int>(v) {}
void check(int const& v) const {
if (v < 0) {
throw "Yikes! A negative integer!";
}
}
};
There you have it -- all of the advantages of externally-generated getter/setter functions, with none of the mess! :)
You could choose to have check() return a bool indicating validity instead of throwing an exception. And you could in principle add a similar method, access(), for catching read references to the property.
EDIT: As Mr. Fooz notes in the comments, the class author can later change the implementation without modifying the logical structure of the class (e.g. by replacing the property<int> x member with a pair of x() methods), although binary compatibility is lost so users will need to recompile their client code whenever such a change is made. This ability to painlessly incorporate future changes is actually the main reason people use getter/setter functions instead of public members in the first place.
Performance note: Because we are using the CRTP to achieve "compile-time polymorphism", there is no virtual-call overhead for providing your own check() in a subclass, and you need not declare it virtual.
As most C++ private members should not be accesible via Get/Set style functions, this seems like a bad idea.
For a simple example of why this is so, consider the C++ std::string class. Its private members probably look something like this (exact implementation not important):
private:
int last, len;
char * data;
Do you believe it makes any sense to provide get/set members for those?
I can't help you with the location of that particular script. However, there are quite a lot of code generation tools. You may even have what you are looking for already part of your IDE. For more debate/input on how, why, and whether to use code generation tools, you might look at this stackoverflow question. I like the accepted answer on that question.
You want a script to generate get/set functions for all of your private members indiscriminately? That wouldn't be a very useful script; you probably no going to find it in Google. If you want to be able to somehow tag your member variable and have getter and/or setter skeletons automatically generated for you, than a IDE macro seems more appropriate. Try Google for that.
I know of one programmer who uses Perl to augment the C preprocessor when it comes to macros (latest version of that project). The basic idea is you would decide on some convention to tell your Perl script when to generate a getter or setter:
struct My_struct {
//set
//get
int x;
int y;
//get
int z;
};
Given code like this, I could write a script to look for comment lines consisting of the comment "get" or "set" on the line(s) before a member variable declaration, and then replace them with simple setters/getters. In the above example I would generate void set_x(int i), int get_x(), and int get_z() after the associated member variable definitions.
A word of warning: do not do this in-place with s///. Instead, scan each line individually, and if you find an appropriate comment line push something that says "I need a getter/setter" onto a stack, then when you see the associated member variable, pop things off of the stack and generate the code.
There are a few devils in the details, but overall that is the idea.