5

Please consider the following code:

using custom_t = std::valarray<unsigned>;
custom_t o;
unsigned acc = std::accumulate(std::cbegin(o), std::cend(o), 0);

g++-5 says

No matching function for call to cbegin(custom_t&)

If I use std::begin(o) and std::end(o) instead, everything works. Is this a compiler bug? The code compiles with Visual Studio 2015.

0xbadf00d
  • 17,405
  • 15
  • 67
  • 107
  • [Compiles in libc++.](http://coliru.stacked-crooked.com/a/e78b7b445c344d4f) I think that libstdc++ is implementing some kind of SFINAE for types that satisfy the Container concept. Since `std::valarray` is not a Container, the call fails. – David G Aug 27 '15 at 17:24

2 Answers2

3

This is a libstdc++ bug, I've just created https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67374

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • 1
    It doesn't make any sense to me, why `std::begin` and `std::end` are specialized for `std::valarray`, but `std::cbegin` and `std::cend` are not. What's the reason? – 0xbadf00d Aug 27 '15 at 17:16
  • 1
    @0xbadf00d the reason is probably noone thought of doing or even specifying that. Which kind of makes sense, considering valarray is meant to be rather lightweight and not so feature-rich. I must admit I've never used valarray myself, because no library I know can actually make use of the additional aliasing restrictions (is there anything else preferable about valarray?) – Marcus Müller Aug 27 '15 at 17:19
  • 1
    *"and so doesn't support all the non-member functions for accessing containers."*, I'm wondering why 1. there is non-member function `std::begin` overloaded for a `const` `valarray`, 2. a template function `std::cbegin` from `` is not picked – Piotr Skotnicki Aug 27 '15 at 17:20
  • I wouldn't be asking without [checking](http://melpon.org/wandbox/permlink/nk9hVzRrwfrSwGkl) – Piotr Skotnicki Aug 27 '15 at 17:27
  • 1
    @PiotrSkotnicki, it's because `` includes `` before defining the `begin` and `end` overloads for valarrays, so they aren't visible to `cbegin` and can't be called. Which looks like a bug. – Jonathan Wakely Aug 27 '15 at 17:30
  • @PiotrSkotnicki, bug report created, thanks for making me take a proper look – Jonathan Wakely Aug 27 '15 at 17:35
-4

There is no

std::cbegin.

Use

unsigned acc = std::accumulate(o.cbegin(), o.cend(), 0);

which feels far more object-oriented.

Marcus Müller
  • 34,677
  • 4
  • 53
  • 94