10

I was reading the documentation for std::any_cast and I find it strange that the API has the cast either return a value to the held object or a pointer to it. Why not return a reference? A copy needs to be made every time the function is called with a non pointer type argument.

I can see that the pointer version of the cast might signal intentions a bit more and might be a bit more clear but why not have the value returned be a reference like this?

template<typename ValueType>
ValueType& any_cast(any* operand);

instead of

template <typename ValueType>
ValueType* any_cast(any* operand);

Further it seems like even if you ask for a reference the cast removes the reference and returns a copy to the stored object see the explanations for the return values for function overloads 1-3 here http://en.cppreference.com/w/cpp/utility/any/any_cast

Curious
  • 20,870
  • 8
  • 61
  • 146
  • 1
    And what if the input pointer is `nullptr`? It can't be dereferenced to satisfy a returned reference. I think what you are really asking about is why the overloads of `any_cast` that take a reference as input return a copy instead of a reference as output, isn't that right? – Remy Lebeau Jan 28 '17 at 02:53
  • 2
    `any_cast` gives a reference if you tell it to. This is like saying `static_cast` always returns a copy. – ildjarn Jan 28 '17 at 02:56
  • The number of valid pointer values of a given type that can't be referenced depends on one's reading of the standard and that standard's evolution, but it is decidedly greater than 0 since it includes the nullpointer. – Cheers and hth. - Alf Jan 28 '17 at 02:58
  • Thinking about it, it seems utterly weird. I guess you or Someone™ will have to look up the original paper or papers, to find the rationale. It doesn't seem very practical, what with exception issue and performance. – Cheers and hth. - Alf Jan 28 '17 at 03:04
  • @RemyLebeau yes I guess so, I understand that the pointer version can be clearer but I am not sure why none of these casts don't return a reference – Curious Jan 28 '17 at 03:06
  • @ildjarn the documentation states that the cast removes the reference, so if you ask for something like `any_cast` you will still get a copy when you pass a reference to an `std::any` object – Curious Jan 28 '17 at 03:07
  • 1
    @Curious: `any_cast` will remove the reference while working on the object internally, but it still returns `Something&` as output. – Remy Lebeau Jan 28 '17 at 03:12
  • @RemyLebeau ah my mistake, that should have been very obvious, don't know how I missed that. Sorry! – Curious Jan 28 '17 at 03:20

1 Answers1

16

You can see a discussion regarding the C++ standard for this here: https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/ngSIHzM6kDQ

Note that Boost has defined any_cast this way for more than a decade, plus it matches static_cast and friends. So if you want a reference, do this:

any_cast<Foo&>(x)

The same as you'd do for the older _casts in C++.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • Yeah but this isn't really a cast. The word "cast" here is a misnomer. It's a device to access the contained object. – Cheers and hth. - Alf Jan 28 '17 at 03:06
  • But if you take a look at the documentation here http://en.cppreference.com/w/cpp/utility/any/any_cast, the reference is removed, right? – Curious Jan 28 '17 at 03:08
  • 2
    @Curious: Internally yes, but not in the output, because `std::remove_reference_t` is not applied to the return type. The return type is whatever you ask for in the template parameter. – Remy Lebeau Jan 28 '17 at 03:13
  • 3
    Just to sum up, with this function to access the object you have to **explicitly opt in** to get a reference, and otherwise, the default, you get the posssibilities of inefficiency and exception issue. With a reasonable design you would have explicitly do a copy to get a copy. So while this answer tells the facts of the situation, it doesn't answer the question, “***why*** not have the value returned be a reference like this”. I can see no reasonable reason. The similarity to cast notation is an aesthetic issue where I absolutely don't share that silly notion of beauty-in-conformity. – Cheers and hth. - Alf Jan 28 '17 at 03:33