Re: Can C++ variadic arguments be enforced to be a single type at
compile time?
Am 14.11.2011 18:46, schrieb Daryle Walker:
This is based on a response I made in another post:
// Don't have C++11 system, so it's not tested
class MyType
{
private:
MyObject* Object;
std::vector<MyObject*> Dependencies;
FillDependencies()
{}
template<typename... Args>
FillDependencies( MyObject&dependency, Args...&dependencies )
{
this->Dependencies.push_back(&dependency );
this->FillDependencies( dependencies );
}
In a former reply I thought you made a typo, but since you repeat this
again here, I have my doubts now. Hence I wonder, why you haven't
responded to my replies to clarify what you actually want. I don't
understand what FillDependencies is supposed to be in a class named
MyType. Grammatically, the declarations look like constructor
declarations, but they the language does not allow to declare a
constructor of type B in a class of type A (where A is different from
B). So, I must say, that I don't understand what this class definition
is supposed to mean.
public:
template<typename... Args>
MyType( MyObject&obj, Args...&dependencies )
: Object{&obj }, Dependencies{}
{
this->Dependencies.reserve( sizeof...(dependencies) );
this->FillDependencies( dependencies );
// ...
}
//...
};
The constructor and dependency-filler methods are templated on the
types of the dependencies, but those dependencies always have to be
MyType, which I try to enforce with FillDependencies. I've never seen
C++ variadic functions like:
MyFunction( int arg1, int... args );
with no templating. Is it just too rare to be in an example, or is it
banned?
It is not "banned", it did already have a well-defined meaning in C++
since 1998 where it declares a function with ellipses equivalent to
MyFunction( int arg1, int, ... args );
C++11 couldn't break that (unfortunately, because C doesn't allow this
declaration without intervening comma). Parameter packs are therefore
always involved with some corresponding template, it could be either of
a type template, a non-type template, or a template template. MyFunction
does not satisfy any of the criteria so far. Even if it just were a
member function of a class template, the parameter parameter expansion
could only by depending on some template type parameter (if it weren't,
the expansion would just be an expansion of constant values, which
doesn't make sense in function parameter list).
If the latter, I just have to do what I have seen in
examples:
template<typename... Args>
MyFunction( int arg1, Args... args );
and use std::enable_if, or similar, to limit Args to int (or something
convertible to int).
Yes.
As a different workaround, I could use a initializer list:
MyType( MyObject&obj, std::intializer_list<MyObject&>
dependencies );
This won't work, because an initializer_list requires it's template
parameter to be of object type, but MyObject& is a reference type, so
the instantiation would be ill-formed.
but then my initializers will have two layers
MyType mt{ obj1, {dep1, dep2}};
instead of a flat list
MyType mt{ obj1, dep1, dep2 };
and I wonder if a flat list is possible (while keeping the first
object mandatory).
Just use a pure initializer-list constructor like
MyType(std::initializer_list<MyObject> dependencies);
Also, if single-type variadic argument lists are banned, why? Is it a
corner case no one thought of, or is there some reason omitting a
template specifier makes C++ variadic arguments not work?
See above.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]