I have found that sometimes functions have very many parameters. A great many of these parameters will be optional and sometimes a group of these options often come from a single other object (so you end up doing foo(Object.GetN(), Object.GetM(), Object.GetK())). A common way to deal with it is to create different overloads for different situations that it might be called:
foo(int n, int m, int k /*, and on and on*/);
foo(bool b, int m/*, ...*/);
foo(int m, int k/*, ...*/);
foo(Object_t object/*, ...*/);
//...
The problem here is that which parameter is which isn't particularly intuitive and you can get quite the surprise when you call a different overload than what you intended.
Recently I had an idea to make it easier to get the function call right and make life easier for myself when dealing with these functions that have many different ways of being called. This solution doesn't cover every possible necessity out there, but it works quite well for me.
Instead of creating different overloads for everything, I would create 1 function that simply takes a variadic number of parameters and then extract possible parameters for use inside the function. As for the parameters, I would wrap them in helper classes that would be created for these functions. This would allow for the user declaring what each integer or boolean or string or what-have-you means instead of relying on positional information within the function's signature.
Instead of foo(n, m) (which going by the names of the variables above suggests a likely bug) you would call foo(OptN(n), OptM(m)) making it completely clear what each parameter is going to be used for and much harder to have a parameter be misinterpreted.
I will include a MCVE at the end if anyone's interested in 1 possible implementation of this.
I have never seen or heard of this technique before, but I also have a hard time believing that I'm the first one to think of it. So, finally, my question is simply does this technique have a name already?
If it doesn't have a name already, I have been calling these functions 'declarative functions' since you declare what each parameter represents explicitly instead of 'positional functions' relying on where the parameter appears to give it its meaning.
MCVE:
#include <iostream>
#include <utility>
struct Option1
{
Option1(bool b):b(b){}
bool b;
bool operator()() const {return b;}
};
struct Option2
{
Option2(int n):n(n){}
int n;
int operator()() const {return n;}
};
struct Group : Option1, Option2
{
Group(bool b, int n):Option1(b), Option2(n){}
};
/*
* Get the option from what the user gave us.
*/
template <class OptionType, class OptionsGetter, class RType>
auto GetOptionImpl(const OptionsGetter & options_getter,
const RType&, std::true_type) ->
decltype(((const OptionType&)options_getter)())
{
return ((const OptionType&)options_getter)();
}
/*
* Get the default value specified since the user didn't pass
* in that option
*/
template <class OptionType, class OptionsGetter, class RType>
RType GetOptionImpl(const OptionsGetter&, const RType & d, std::false_type)
{
return d;
}
/**
* Returns the value of the option OptionType if the user
* passed that in (inside OptionsGetter) and returns the
* default value if they didn't pass it in.
*/
template <class OptionType, class OptionsGetter, class RType>
auto GetOption(const OptionsGetter & oOptionsGetter,
const RType & oDefault) ->
decltype(std::declval<OptionType>()())
{
return GetOptionImpl<OptionType>(oOptionsGetter, oDefault,
std::is_base_of<OptionType, OptionsGetter>());
}
template <class ... Params>
void foo(Params ... params)
{
struct ParamsGetter : Params...
{
ParamsGetter(Params ... p): Params(p)...{}
} params_getter(params...);
if(GetOption<Option1>(params_getter, false))
std::cout << "Option 1 was true ";
else
std::cout << "Option 1 was false ";
std::cout << "Option 2: " << GetOption<Option2>(params_getter, 3) << '\n';
}
int main()
{
foo(Option1{true}, Option2{22});
foo();
foo(Option2{1});
foo(Group(true, 2));
}
Output:
Option 1 was true Option 2: 22
Option 1 was false Option 2: 3
Option 1 was false Option 2: 1
Option 1 was true Option 2: 2
As mentioned in a comment, this concept is called named parameter. See the explanation on wikipedia, as well as for instance this proposal to introduce it in C++.
I think this is commonly called an opaque typedef or a strong typedef. The idea is to solve the exact problem you're describing - you have types that have integral values but you want to make it possible to explicitly set them.
For more motivation on this concept, you can see this proposal for inclusion in the language and Boost's implementation of it.
Related
I have 2 issues in a template class I'm building. I've included example code below. First question is whether I can coerce the auto type deducted for a templated class. i.e.:
auto p = myvar;
where myvar is T<...>, could I force auto to detect Q<...>? This is simplified. Read on for a more clear explanation.
Edited for clarity: Let me explain what I'm doing. And I'd also like to indicate that this style code is working on a large-scale project perfectly well. I am trying to add some features and functions and in addition to smooth out some of the more awkward behaviors.
The code uses templates to perform work on n-dimensional arrays. The template has a top-level class, and a storage class underneath. Passing the storage class into the top level class allows for a top level class which inherits the storage class. So I start with NDimVar, and I have NDimStor. I end up with
NDimVar<NDimStor>
The class contains NO DATA except for the buffer of data:
class NDimStor<size_t... dimensions> {
int buffer[Size<dimensions...>()]
}
This makes the address of the class == the address of the buffer. This is key to the whole implementation. Is this an incorrect assumption? (I can see this works on my system without any issues, but perhaps this isn't always the case.)
When I create NDimVar<NDimStor<10,10>> I end up with a 10x10 array.
I have functions for getting pieces of the array, for example:
NDimVar<NDimStor<dimensions...>>::RemoveDim & get(int index);
This creates a new 1d array of 10 elements out of the 2d 10x10 array:
NDimVar<NdimStor<10>>
In order to return this as a reference, I use a reinterpret_cast at the location of the data I want. So in this example, get(3) would perform:
return reinterpret_cast<NDimVar≤NDimStor<dimensions...>>::RemoveDim&>(buffer[index * DimensionSumBelow<0>()]);
DimensionSumBelow<0> returns the sum of elements at dimensions 1+, i.e. 10. So &buffer[30] is the address of the referenced 1d NDimVar.
All of this works very well.
The only issue I have is that I would like to add on overlays. For example, be able to return a reference to a new class:
NDimVar<NDimPermute<NDimStor<10,10>,1,0>>
that points to the same original location along with a permutation behavior (swapping dimensions). This also works well. But I would like for:
auto p = myvar.Permute<1,0>()
to create a new copy of myvar with permuted data. This would work if I said:
NDimVar<NDimStor<10,10>> p = myvar.Permute<1,0>().
I feel that there is some auto type deduction stuff I could do in order to coerce the auto type returned, but I'm not sure. I haven't been able to figure it out.
Thanks again,
Nachum
What I want is:
1. Create temporary overlay classes on my storage, e.g. A_top<A_storage> can return a type called A_top<A_overlay<A_storage>> without creating a new object, it just returns a reference to this type. This changes the way the storage is accessed. The problem is upon a call to auto. I don't want this type to be instantiated directly. Can I modify the return to auto to be an original A_top?
#include <iostream>
using namespace std;
class A_storage {
public:
float arr[10];
A_storage () {
}
float & el (int index) {
return arr[index];
}
};
template <typename T> class A_overlay : T {
private:
A_overlay () {
cout << "A_overlay ()" << endl;
}
A_overlay (const A_overlay &) {
cout << "A_overlay (&)" << endl;
}
public:
using T::arr;
float & el (int index) {
return arr[10 - index];
}
};
template <typename T> class A_top;
template <typename T> class A_top : public T {
public:
A_top () {
}
A_top<A_overlay<A_storage>> & get () {
return reinterpret_cast<A_top<A_overlay<A_storage>>&>(*this);
}
};
using A = A_top<A_storage>;
int main (void) {
A a;
auto c = a.get(); // illegal - can i auto type deduce to A_top<A_storage>?
return 0;
}
If a function accepts (A_top<A_storage> &) as a parameter, how can I create a conversion function that can cast A_top<A_overlay<A_storage>>& to A_top<A_storage>& ?
Thanks,
Nachum
First, your design doesn't look right to me, and I'm not sure if the behaviour is actually well-defined or not. (Probably not.)
In any case, the problem is not with auto. The error is caused by the fact that the copy constructor of A_overlay is private, while you need it to copy A_top<A_overlay<A_storage>> returned by a.get() to auto c.
(Note that the auto in this case obviously gets deduced to A_top<A_overlay<A_storage>>, I assume you made a typo when said that it's A_top<A_storage>.)
Also note that A_storage in A_top::get() should be replaced with T, even if it doesn't change anything in your snippet because you only have T == A_storage.
If a function accepts (A_top &) as a parameter, how can I create a conversion function that can cast A_top> to A_top& ?
Ehm, isn't it just this:
return reinterpret_cast<A_top<A_storage>&>(obj);
reinterpret_cast should almost never be used. It essentially remove any compiler validation that the types are related. And doing unrelated cast is essentially undefined behavior as it essentially assume that derived classes are always at offset 0...
It does not make any sense to write such code. It is not maintainable and hard to understand what you are trying to achieve. It look like you want to pretend that your A_top<A_storage> object is a A_top<A_overlay<A_storage>> object instead. If this is what you want to do, then declare A alias as that type.
In your code, it look like you want to invert the indexing so that item at position 10 is returned when you ask item at position 0 and vice versa. Do you really think, that it is obvious from your obfuscated code? Never write such bad code.
Something like
class A_overlay {
public:
float & el (int index) { return arr[10 - index]; }
private:
A_storage arr;
};
would make much more sense than your current code.
No cast needed.
Easy to understand.
Well defined behavior.
You might keep your job.
And obviously, you would update the following line as appropriate:
using A = A_top<A_storage>;
Also, if A_top has no useful purpose, then why not using A_overlay directly? And why are you using template if A_storage is not a template? Do you really want to reuse such mess elsewhere in your code base.
Obviously, your code inheritance does not respect IS-A relationship if your write such code. So it is clearly a bad design!
C++ has some sort of duck typing for types given by template parameters. We have no idea what type DUCK1 and DUCK2 will be, but as long as they can quack(), it will compile and run:
template <class DUCK1, class DUCK2>
void let_them_quack(DUCK1* donald, DUCK2* daisy){
donald->quack();
daisy->quack();
}
But it's a bit inconvenient to write. When I do absolutely not care what actual types DUCK1 and DUCK2 are but rather want to fully use the idea of duck typing, then I would like to have something sligthly different than above:
I'd like to omit writing a template parameter list that is repetitive and mostly meaningless (Just imagine what would happen if there are 7 ducks...)
I'd like to make it a bit more explicit that the types are never used and that it's only the interface that matters.
I'd like to have sort of an interface annotation/check. Make somehow clear what interface is expected behind the type. (That's, however, a bit in contrast of duck typing.)
Does C++ offer any features to achieve one or more of the 3 ideas?
(I know that virtual inheritance is the method of choice in most cases to implement such patterns, but the question here is specifically about the case of static polymorphism.)
Concerning questions 1 and 2: since C++14 you can omit explicit template <typename ... boilerplate and use auto, but only in lambdas:
auto let_them_quack = [] (auto & donald, auto & daisy){
donald.quack();
daisy.quack();
};
(yes, I prefer references to pointers). GCC allows to do so in usual functions as an extension.
For the question 3, what you are talking about are called concepts. They existed in C++ for a long time, but only as a documentational term. Now the Concepts TS is in progress, allowing you to write something like
template<typename T>
concept bool Quackable = requires(T a) {
a.quack();
};
void let_them_quack (Quackable & donald, Quackable & daisy);
Note that it is not yet C++, only a technical specification in progress. GCC 6.1 already seems to support it, though. Implementations of concepts and constraints using current C++ are possible; you can find one in boost.
I'd like to omit writing a template parameter list that is repetitive
and mostly meaningless (Just imagine what would happen if there are 7
ducks...)
For that you could use variadic templates and do something like the following:
template<typename DUCK>
void let_them_quack(DUCK &&d) {
d.quack();
}
template<typename DUCK, typename... Args>
void let_them_quack(DUCK &&d, Args&& ...args) {
d.quack();
let_them_quack(std::forward<Args>(args)...);
}
Live Demo
#2 and #3 are sort of taken care of by the fact that the code will not compile, and throw a compilation error, if the given classes don't implement the interface. You could also make this formal:
class duck {
public:
virtual void quack()=0;
};
Then declare the parameters to the function as taking a pointer to a duck. Your classes will have to inherit from this class, making the requirements for let_them_quack() crystal clear.
As far as #1 goes, variadic templates can take care of this.
void let_them_quack()
{
}
template <typename ...Args>
void let_them_quack(duck* first_duck, Args && ...args) {
first_duck->quack();
let_them_quack(std::forward<Args>(args)...);
}
You will be able to make it look preetier with concept (not yet in standard - but very close):
http://melpon.org/wandbox/permlink/Vjy2U6BPbsTuSK3u
#include <iostream>
template<typename T>concept bool ItQuacks(){
return requires (T a) {
{ a.quack() } -> void;
};
}
void let_them_quack2(ItQuacks* donald, ItQuacks* daisy){
donald->quack();
daisy->quack();
}
struct DisneyDuck {
void quack(){ std::cout << "Quack!";}
};
struct RegularDuck {
void quack(){ std::cout << "Quack2!";}
};
struct Wolf {
void woof(){ std::cout << "Woof!";}
};
int main() {
DisneyDuck q1, q2;
let_them_quack2(&q1, &q2);
RegularDuck q3, q4;
let_them_quack2(&q3, &q4);
//Wolf w1, w2;
//let_them_quack2(&w1, &w2); // ERROR: constraints not satisfied
}
output:
Quack!Quack!Quack2!Quack2!
As you can see, you will be able to: omit writing a template parameter list, ItQuacks is quite explicit so types are never used and that it's only the interface that matters takes place. This I'd like to have sort of an interface annotation/check. also takes place, concept use will also give you meaningfull error message.
We only need to write one version of the function:
#include <utility>
template<typename... Quackers>
void let_them_quack(Quackers&& ...quackers) {
using expand = int[];
void(expand { 0, (std::forward<Quackers>(quackers).quack(), 0)... });
}
struct Duck {
void quack() {}
};
int main()
{
Duck a, b, c;
let_them_quack(a, b, c, Duck());
}
I would like to share a function across template instantiations, and wonder whether there's a way to do that.
_____ edit to clarify question _____
Lets look at the following example
#include <array>
template <unsigned int K>
class kd_tree
{
public:
using kd_point = std::array<float, K>;
bool isValid(const kd_point &kdPoint) const
{
for (unsigned i = 0; i < K; i++)
if ( isnan(kdPoint[i]) ||
kdPoint[i] == numeric_limits<float>::infinity() ||
kdPoint[i] == -numeric_limits<float>::infinity() )
return false;
return true;
}
};
for each value of K, a new value of isValid will be created that differs by nothing except the concrete value of K. It certainly doesn't need K to use kd_point's operator[]
Question is whether there's a way to take isValid out of the class and make it a function that accepts a kd_point & a K as parameters, and check the point, thus saving in executable size on multiple copies of it, e.g. one for K=2 & another for K=3.
I'm not sure I've understood the question, but could a factory like the following one solve the problem?
void fn() { }
template<void(*Function)()>
class C {
C() = default;
public:
static C<Function>* create() {
return new C<Function>{};
}
};
using CfnFactory = C<fn>;
int main() {
C<fn> *c = CfnFactory::create();
}
Note that the example above applies well also with member functions, it's only a minimal example of a possible solution from which to start (of course, if I got the problem).
The idea is to inject in the factory the function to be used to create instances of your type, so that all of them will rely on the same function. This way you can also create multiple factories based on different functions and mix together the returned objects (the last point requires a base, non-template class, but it's quite easy to do).
In any case, I strongly suggest you to reduce the amount of code in your example to a mvce.
It would help the reader and it will increase the chances to get a valid response.
I have the following situation. We are writing a library which has a class which has a lot of fields (majority) of it depending on some optional fields which have "flags" (bits in a number basically) if the optional field is present or not.
The fields of the class are required to be public for easier access (I know it's bad), and 3rd party developers will read the header files (beside of their documentation) in order to get familiar with the structure and the connection of various fields to their corresponding options.
The problem is, the customer wants to make easy for their developers to identify which fields depends on which optional structure with as little effort as possible.
One of the solutions is to put a comment above or after the field (class member) name telling it uses this option field. This is the basic choice.
However the class is already over populated with around 500 members (fields) so I don't know that if adding extra 500 lines, or long comments will add to the quality of it.
We came up with the following constructs:
#define DEPENDS
#define ON
#define BIT(x) ((x)-1)
#define OF(x)
struct source{};
struct options
{
options(const source&) {}
};
template <int BITIDX>
struct optional
{
optional(const options&) {}
};
struct something
{
// this constructor will be implemented in the CPP
// so the user (developer) will not see it
something (const source& src) :
msource(src), initial_options(src), other_options(src),
field1(initial_options), field2(other_options) {}
options initial_options;
options other_options;
optional<DEPENDS ON BIT(1) OF (initial_options)> field1;
optional<DEPENDS ON BIT(1) OF (other_options) > field2;
source msource;
};
int main()
{
source s;
something a(s);
}
but obviously this is not much better due to namespace pollution, macros, etc ...
So, the question: is there a better way to achieve our goal to provide a meaningful way of presenting the connection of a field from a bit of an option?
(Please note, C++11 class member initialization is NOT allowed, otherwise I would not ask this question :) We have to stick to older compilers :( )
struct something
{
enum OptionGroup { Initial, Other /*...*/ };
enum InitialFields { A, B /*...*/ };
enum OtherFields { X, Y /*...*/ };
So, we enumerated the fields A,B etc. inside each optional group. Since they're zero-based and incrementing, the enumerated values will tell us which bit represents each field.
template <typename TYPE, OptionGroup GROUP, int BIT>
struct Optional {
TYPE val;
operator TYPE& () { return val; }
operator TYPE const& () const { return val; }
};
This records the group of an optional field, and which bit within that group represents it. You didn't say what the type of your fields is, so I made it generic. You also didn't say how you initialize them, so it might need constructors etc.
int mandatory1;
int initialOptions;
Optional<int, Initial, A> a;
Optional<int, Initial, B> b;
int otherOptions;
Optional<double, Other, X> x;
And here we have the actual storage for a sequence of mandatory and optional fields.
now, we need some way to get the flags for each group:
template <OptionGroup GROUP> int getGroupFlags();
with that, we can check whether a given field is valid ...
template <typename TYPE, OptionGroup GROUP, int BIT>
bool isValid(Optional<TYPE,GROUP,BIT> const &field) {
return getGroupFlags<GROUP>() & (1 << BIT);
}
};
Sadly, recording the association between the enumeration and the group is still manual (this is where being able to merge both sets of option flags into a single bit field would have made life easier)
template <> int something::getGroupFlags<something::Initial>() { return intialOptions; }
template <> int something::getGroupFlags<something::Other>() { return otherOptions; }
This could be cleaned up considerably (eg, by binding each optional group into a single struct instead of hard-coding the nasty OptionGroup->flag field relationship), but this seems like the least work.
This question was closed as exact duplicate since I chose a misleading question title. It was not wrong but suggested an issue often discussed, e.g. in this question. Since the content is about a more specific topic never covered on Stackoverflow I would like the question to be reopened. This happened now, so here goes the question.
I have given a function expecting three integer values as parameters length(int x, int y, int z);. I cannot modify this function, e.g. to accept a struct or tuple of whatever as single parameter.
Is there a way in C++ to write another function which can be used as single argument to the function above, like length(arguments());?
Anyhow the return type of that function arguments(); seems to need to be int, int, int. But as far as far as I know I can't define and use functions like this in C++. I know that I could return a list, a tuple, a struct or a class by arguments(). The question was closed because some people thought I would have asked about this. But the difficult part is to pass the tuple, or struct, or whatever as the three given integer parameters.
Is this possible and if yes, how is that possible in C++? A solution making use of C++11 would be fine.
I don't think there is any direct way of doing what you want, but here is a C++11 technique that I use in several places of my code. The basic idea is to use a template function which I've called call_on_tuple to take a function argument f as well as a tuple of further arguments, expand the tuple and call the function on the expanded list of arguments:
template <typename Fun, typename... Args, unsigned... Is>
typename std::result_of<Fun(Args...)>::type
call_on_tuple(Fun&& f, std::tuple<Args...>&& tup, indices<Is...>)
{ return f(std::get<Is>(tup)...); }
So the idea is that instead of calling
length(arguments());
you would call
call_on_tuple(length,arguments());
This assumes that arguments() is changed so it returns a std::tuple<int,int,int> (this is basically the idea from the question you cited).
Now the difficult part is how to get the Is... argument pack, which is a pack of integers 0,1,2,... used to number the elements of the tuple.
If you are sure you'll always have three arguments, you could use 0,1,2 literally, but if the ambition is to make this work for any n-ary function, we need another trick, which has been described by other posts, for example in several answers to this post.
It's a trick to transform the number of arguments, i.e. sizeof...(Args) into a list of integers 0,1,...,sizeof...(Args):
I'll put this trick and the implementation of call_on_tuple in a namespace detail:
namespace detail {
template <unsigned... Is>
struct indices
{ };
template <unsigned N, unsigned... Is>
struct index_maker : index_maker<N-1,N-1,Is...>
{ };
template <unsigned... Is>
struct index_maker<0,Is...>
{ typedef indices<Is...> type; };
template <typename Fun, typename... Args, unsigned... Is>
typename std::enable_if<!std::is_void<typename std::result_of<Fun(Args...)>::type>::value,
typename std::result_of<Fun(Args...)>::type>::type
call_on_tuple(Fun&& f, std::tuple<Args...>&& tup, indices<Is...>)
{ return f(std::get<Is>(tup)...); }
}
Now the actual function call_on_tuple is defined in global namespace like this:
template <typename Fun, typename... Args>
typename std::enable_if<!std::is_void<typename std::result_of<Fun(Args...)>::type>::value,
typename std::result_of<Fun(Args...)>::type>::type
call_on_tuple(Fun&& f, std::tuple<Args...>&& tup)
{
using std::tuple;
using std::forward;
using detail::index_maker;
return detail::call_on_tuple
(forward<Fun>(f),forward<tuple<Args...>>(tup),typename index_maker<sizeof...(Args)>::type());
}
It basically calls detail::index_maker to generate the list of increasing integers and then calls detail::call_on_tuple with that.
As a result, you can do this:
int length(int x, int y, int z)
{ return x + y + z; }
std::tuple<int,int,int> arguments()
{ return std::tuple<int,int,int> { 1 , 2 , 3 }; }
int main()
{
std::cout << call_on_tuple(length,arguments()) << std::endl;
return 0;
}
which is hopefully close enough to what you needed.
Note. I have also added an enable_if to ensure this is only used with functions f that actually return a value. You can readily make another implementation for functions that return void.
Sorry again for closing your question prematurely.
PS. You'll need to add the following include statements to test this:
#include <tuple>
#include <type_traits>
#include <iostream>
It is not possible, C++ does not allow to provide 3 return values natively that can be used as 3 separate input arguments for another function.
But there are 'tricks' to return multiple values. Although none of these provide a perfect solution for your question, as they are not able to be used as a single argument to length() without modifying length().
Use a container object, like a struct, tuple or class
typedef struct { int a,b,c; } myContainer;
myContainer arguments(int x, int y, int z) {
myContainer result;
result.a = 1;
// etc
return result;
}
myContainer c = arguments(x, y, z);
length(c.a, c.b, c.c);
The trick is to overload the length() function, so it looks like you can use it with a single argument:
void length(myContainer c) {
length(c.a, c.b, c.c);
}
length(arguments());
Of course you could optimize it further, by using inline, macros, and what not.
I know it is still not exactly what you want, but I think this is the closest approach.
You need to declare a struct { int a, b, c; } or something similar (a class would work too) - I take it you have been programming python or php or some such.
Most programming languages would do this through some form of adapter function. That is a function that will take as argument the function to call (here length) and the arguments to call it with. You can probably build something similar in C++ with templates. Look at the functional header to get inspiration.
A language that natively provides what you are looking for is Perl. You can write:
sub arguments {
return 1, 2, 3;
}
sub length {
my ($p1, $p2, $p3) = #_;
# … Work with $p1, $p2 and $p3
}
length(arguments());
Pass in the arguments by reference so you can change them without returning or return a struct. You can only return a single value from a function.
we can only return one value. but in case you want to return multiple value you can use an array or define a object or a structure
int* arguments() {
int x[1,4,6]
return x;
};
void length(int i[]);
length(arguments());