Re: Initializer lists vs. 0 or 1 items
Am 28.08.2011 03:07, schrieb Daryle Walker:
On Aug 27, 8:55 am, Daniel Kr?gler<daniel.krueg...@googlemail.com>
wrote:
Am 27.08.2011 04:24, schrieb Daryle Walker:
[..]
Well, it's a complex-number type, so its implementation would be like
"T c_[2]", so the default construction code would work just fine.
I haven't read it this way, because why in heaven should you then use an
initializer list constructor here? Why not using a normal two-argument
constructor with default arguments as in:
template<typename T>
class my_complex
{
public:
my_complex() = default;
my_complex(T first, T second = T());
};
[TRUNCATE]
I think I overgeneralized. The theoretical class I had in mind for
this question would have a variable number of elements, controlled by
a second (non-type) template parameter. The number of components
could end up being either less or greater than 2, so a constructor
with a fixed number of elements, besides 0 or 1, may end up being
inappropriate. That's why I think my only choices for a generalized
class would be a default constructor (0 specified elements), an
(implicit) single-argument constructor (1 specified element), or an
arbitrary amount of elements using these new-style initializer lists.
Your description indicates that you should better use variadic template
parameters instead of initializer lists, which have no good way of
constraining them by size. The following gives a hint how to realize that:
#include <type_traits>
template<class To, class... U>
struct all_convertible;
template<class To>
struct all_convertible<To> : std::true_type {};
template<class To, class U>
struct all_convertible<To, U> : std::is_convertible<U, To>::type
{
};
template<class To, class U, class... R>
struct all_convertible<To, U, R...> : std::conditional<
std::is_convertible<U, To>::value, all_convertible<To, R...>,
std::false_type>::type::type
{
};
template<class T, unsigned D>
class my_complex {
static_assert(D > 0, "Dimension out of bounds");
T data[D];
public:
my_complex() = default;
template<class... Args, class =
typename std::enable_if<
(sizeof...(Args) > 0) && (sizeof...(Args) <= D) &&
all_convertible<T, Args...>::value
>::type
>
my_complex(Args... args);
};
But the main question was could an initializer list of one element act
transparently like a single-argument constructor. The answer seems to
be no, since one requires braces and the other must omit them, but we
can have the single-argument constructor delegate to the initializer-
list constructor to save code. (And we can have default construction
use the initializer-list constructor too.)
Yes, a single-argument constructor cannot be expressed by an
initializer-list constructor, because there does not exist a language
construction of a "default-single-argument" constructor similar to a
default constructor.
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! ]