How could comma separated initialization such as in Eigen be possibly implemented in C++?
The basic idea is to overload both the <<
and the ,
operators.
m << 1
is overloaded to put 1
into m
and then returns a special proxy object – call it p
– holding a reference to m
.
Then p, 2
is overloaded to put 2
into m
and return p
, so that p, 2, 3
will first put 2
into m
and then 3
.
A similar technique is used with Boost.Assign, though they use +=
rather than <<
.
initializing a static eigen matrix with comma initialization
Oh, I got this.
This code:
s_idRotationZinverse.col(0) << s_yAxis;
isn't a declaration; it's a statement that has to be inside a function body.
You're probably trying to execute it outside of any function, which is syntactically incorrect and causes the error you mentioned.
You might have been tricked by the Eigen documentation, which calls this syntax "comma initialization" where it should be "comma assignment" or so. Initialization is when you give the variable a value when it's defined, not as a separate step. Initialization is syntactically a part of the declaration, so it can be done outside of function bodies.
I suggest to fork Eigen to support the new std::initializer_list
-based initialization (if it's not done yet) and submit a pull request.
When to Overload the Comma Operator?
Let's change the emphasis a bit to:
When should you overload the comma?
The answer: Never.
The exception: If you're doing template metaprogramming, operator,
has a special place at the very bottom of the operator precedence list, which can come in handy for constructing SFINAE-guards, etc.
The only two practical uses I've seen of overloading operator,
are both in Boost:
- Boost.Assign
- Boost.Phoenix – it's fundamental here in that it allows Phoenix lambdas to support multiple statements
operator with multiple parameters
No, that is not possible.
The closest you can come would be something like:
anyType operator<<(std::pair<arg, arg> p)
{
DoSomethingWith(p.first);
DoSomethingWith(p.second);
return (*this);
}
anyvar << std::make_pair(a1, a2);
Alternatively, you could do something much more complicated to effectively curry the call to your operator, by having anyType::operator<<(arg)
return a temporary object which just holds on to its argument and implements a different tempObject::operator<<(arg)
which actually does the work. You can then call that as anyvar << arg1 << arg2
. I really doubt whether it is worth the trouble, aside from being a learning experience.
Something similar to that style is often used in the "builder" pattern, but using member functions rather than an explicit operator. That's useful because you can arrange to effectively make configuration arguments order-independent.
Template for variable length initializer
Don't use the comma initializer syntax in this setting, it's going to be cumbersome. This syntax is used for readability when using literals, which is not your case.
Instead, I would recommend something like:
template<typename T1, typename T2, unsigned int SIZE, unsigned int INDEX>
struct gather {
gather(Array<T1,SIZE,1> &to,
const Array<T2,Dynamic,1> &from,
const Array<int,SIZE,1> &index)
{
to.col(INDEX) = from[index[INDEX]];
gather<T1,T2,SIZE,INDEX+1>(to,from, index);
}
};
template<typename T1, typename T2, unsigned int SIZE>
struct gather<T1,T2,SIZE,SIZE>{
gather(Array<T1,SIZE,1> &to,
const Array<T2,Dynamic,1> &from,
const Array<int,SIZE,1> &index)
{
}
};
which nicely produces the same effect, but statically (no loop).
I am using a struct here because of the partial template specialization restriction on functions, but it should come down to the same, because of inlining.
What is the easiest way to initialize a std::vector with hardcoded elements?
One method would be to use the array to initialize the vector
static const int arr[] = {16,2,77,29};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );
Related Topics
Difference Between | and || , or & and &&
Function Already Defined Error in C++
Name Hiding and Fragile Base Problem
What Are the Operations Supported by Raw Pointer and Function Pointer in C/C++
Unordered Set of Pairs, Compilation Error
Setting Pointer to Arbitrary Dimension Array
Passing Constexpr Objects Around
Understanding Std::Atomic::Compare_Exchange_Weak() in C++11
Opengl: Glflush() VS. Glfinish()
Borderless Window with Drop Shadow
Does New Line Character Also Flush the Buffer
Remote Debugging C++ Applications with Eclipse Cdt/Rse/Rdt
Apply Function to All Eigen Matrix Element
Qt MACro Keywords Cause Name Collisions
Deleted Function in Std::Pair When Using a Unique_Ptr Inside a Map
Constraining the Existing Boost.Spirit Real_Parser (With a Policy)
What Happens When I Assign a Number Larger Than Int_Max to an Int