Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: decltype( a )::value_type

38 views
Skip to first unread message

Sam

unread,
Jul 30, 2018, 5:59:11 PM7/30/18
to
Stefan Ram writes:

> I'm drafting my lesson about »::std::array«.
> This is the example program for »value_type«:
>
> main.cpp
>
> #include <array>
> #include <initializer_list>
> #include <iostream>
> #include <ostream>
> #include <string>
>
> using namespace ::std::literals;
>
> int main()
> { { ::std::array const a{ 4, 2, 7 };
> decltype( a )::value_type v = ::std::get< 0 >( a );
> ::std::cout << v << '\n'; }
>
> { ::std::array const a{ "alpha"s, "gamma"s, "delta"s };
> decltype( a )::value_type v = ::std::get< 0 >( a );
> ::std::cout << v << '\n'; }}
>
> transcript
>
> 4
> alpha
>
> So, is »decltype( a )::value_type« here the most elegant /
> natural / concise way to express that type or is there a
> better way? (Since this is intended to show off »value_type«,
> »value_type« should appear in the answer. So, »auto v = ...«
> would not be helpful.)

I know of no other way to reference the type of the values in a container,
other than it's value_type.

As an aside when one's "drafting a lesson": it's true that it's useful to
point out why someone might want to explicitly specify "::std" in this
manner; as well as go over what "::std::this" or "::std::that" means, and
point out what this does, and why. But overusing the double-colons like that
makes C++ look like bad Perl.

I happen to like Perl. And I use Perl. And there's nothing wrong with Perl,
but there's everything wrong with bad Perl. And "::std::this" and
"::std::that" makes the whole thing, above, look like bad Perl or the C++
version of the obfuscated C context, and the most it would accomplish is
make everyone's eyes bleed.

So let's just stick to simply "std::this" or "std::that", to make the end
result look like elegant C++ (and using sensible identation would also be a
plus). This will still be free of the "using namespace std;" annoyance, but
without going to the other extreme of spraying "::" everywhere, merely to
show off one's pedantic understanding of C++, but also making the resulting
code more convoluted than it needs to be.

Manfred

unread,
Jul 30, 2018, 6:26:54 PM7/30/18
to
On 07/30/2018 11:18 PM, Stefan Ram wrote:
> So, is »decltype( a )::value_type« here the most elegant /
> natural / concise way to express that type or is there a
> better way? (Since this is intended to show off »value_type«,
> »value_type« should appear in the answer. So, »auto v = ...«
> would not be helpful.)

things like value_type are most useful with template (meta)programming,
so it could be useful to show its use with template type arguments,
instead of decltype:


#include <array>
#include <initializer_list>
#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

template<typename Container>
void PrintFirstOf(const Container& c)
{
typename Container::value_type v = std::get<0>(c);

std::cout << v << std::endl;
}

int main()
{
{
::std::array const a{ 4, 2, 7 };
PrintFirstOf(a);
// decltype( a )::value_type v = ::std::get< 0 >( a );
// ::std::cout << v << '\n';
}

{
::std::array const a{ "alpha"s, "gamma"s, "delta"s };
PrintFirstOf(a);
// decltype( a )::value_type v = ::std::get< 0 >( a );
// ::std::cout << v << '\n';
}
}

As a side effect it would be probably good to add here some assurance
that the size oft he array is > 0

Alf P. Steinbach

unread,
Jul 31, 2018, 1:07:00 AM7/31/18
to
On 30.07.2018 23:18, Stefan Ram wrote:
> I'm drafting my lesson about »::std::array«.
> This is the example program for »value_type«:
>
> main.cpp
>
> #include <array>
> #include <initializer_list>
> #include <iostream>
> #include <ostream>
> #include <string>
>
> using namespace ::std::literals;
>
> int main()
> { { ::std::array const a{ 4, 2, 7 };
> decltype( a )::value_type v = ::std::get< 0 >( a );
> ::std::cout << v << '\n'; }
>
> { ::std::array const a{ "alpha"s, "gamma"s, "delta"s };
> decltype( a )::value_type v = ::std::get< 0 >( a );
> ::std::cout << v << '\n'; }}
>
> transcript
>
> 4
> alpha
>
> So, is »decltype( a )::value_type« here the most elegant /
> natural / concise way to express that type or is there a
> better way?<

`auto` comes to mind.

As well as `decltype( +*a.begin() )`.


< (Since this is intended to show off »value_type«,
> »value_type« should appear in the answer. So, »auto v = ...«
> would not be helpful.)

An example where `value_type` is useful information could be some
interaction with some code that requires `value_type`. Yes I know that's
circular to some degree. But that's reality: much of this stuff is only
needed when using code that (needlessly?) depends on it.

Cheers!,

- Alf



Juha Nieminen

unread,
Jul 31, 2018, 2:08:09 AM7/31/18
to
Stefan Ram <r...@zedat.fu-berlin.de> wrote:
> #include <iostream>
> #include <ostream>

Rather redundant, don't you think?

Alf P. Steinbach

unread,
Jul 31, 2018, 5:37:13 AM7/31/18
to
With C++11 and later, yes.

With C++03 it was /formally/ required for the definition of << and for
std::endl, although ~all the examples in the standard that used text
output failed to include <ostream>.

Happily in ISO standards examples aren't normative, otherwise there
would have been a formal self-contradiction.


Cheers!,

- Alf

Manfred

unread,
Jul 31, 2018, 6:30:55 AM7/31/18
to
On 7/31/2018 7:06 AM, Alf P. Steinbach wrote:
> An example where `value_type` is useful information could be some
> interaction with some code that requires `value_type`. Yes I know that's
> circular to some degree. But that's reality: much of this stuff is only
> needed when using code that (needlessly?) depends on it.

I'm not sure it is that needless - I would say it is not uncommon to
encounter value_type or similar type members when using template
libraries (the standard library being the first obvious example)

Another example is the boost library, recalling an older post where I
elaborated on a suggestion of yours:

> template< typename Range >
> bool is_even(const typename boost::range_value<Range>::type& x) { return x.index()%2 == 0; }

Here range_type, although with a different construct than value_type,
serves the same purpose: accessing a dependent type nested inside a
class template.

Juha Nieminen

unread,
Aug 5, 2018, 3:01:05 AM8/5/18
to
Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
> On 31.07.2018 08:08, Juha Nieminen wrote:
>> Stefan Ram <r...@zedat.fu-berlin.de> wrote:
>>> #include <iostream>
>>> #include <ostream>
>>
>> Rather redundant, don't you think?
>
> With C++11 and later, yes.

Given that the code is C++11, it is thus literally redundant.

Alf P. Steinbach

unread,
Aug 5, 2018, 4:45:38 AM8/5/18
to
That's a good point.

I was thinking mainly that Stefan's conventions for his course materials
possibly predate C++11.


Cheers!,

- Alf

0 new messages