0

I have a struct InferValueType which shall be implicitly convertible to any other type including reference types. I accomplish this using the following code.

struct InferValueType {
    // ...

    template <typename Type>
    operator Type() const && {
        // ...
    }

    // We need this special version to allow conversions to reference types
    template <typename Type>
    operator Type&() const & {
        // ...
    }
};

InferValueType is never instantiated by the the user, instead I provide it as the return value of a function.

const InferValueType read();

The combination of InferValueType and read allows the user to write lazy code like this:

int i = read();
MyType t1 = read();
MyType& t2 = read();
const MyType& t3 = read();

I have tested this against GCC 4.8, 4.9, 5, 6 and Clang 3.7 and 3.8. Only GCC 4.8 complains about an ambiguity.

conversion from ‘const InferValueType’ to ‘int’ is ambiguous
conversion from ‘const InferValueType’ to ‘MyType’ is ambiguous

I assume this is because int and MyType can be constructed using const int& and const MyType& respectively.

Question: Is this a peculiarity of GCC before 4.9.2 or is it actually an ambiguity under C++11?

Complete example is here.

Ole
  • 36
  • 3
  • What's the point of const && ? http://stackoverflow.com/questions/8610571/what-is-rvalue-reference-for-this Please show more code, including constructors. – Johan Lundberg Jul 06 '16 at 00:16
  • 2
    I'd be curious to see what you are planning to return from `operator Type&()`. Who's going to manage the lifetime of the `Type` object that the reference refers to? – Igor Tandetnik Jul 06 '16 at 00:40
  • https://github.com/vapourismo/luwra/blob/master/lib/luwra/stack.hpp#L46 – Ole Jul 06 '16 at 01:06
  • `const &&` is used because the the conversion operator is not directly overloadable for `Type` and `Type` – Ole Jul 06 '16 at 01:10
  • No special constructor is involved: https://github.com/vapourismo/luwra/blob/master/lib/luwra/values.hpp#L42 – Ole Jul 06 '16 at 01:13
  • As far as I can tell: `InferValueType::operator T&()` returns `Value::read()`. `Value` is effectively synonymous with `Value`, and its `read()` returns `Type` temporary, by value. Put together, `InferValueType::operator T&()` returns a dangling reference (which used to refer to a temporary that has already been destroyed); any attempt to use this reference would exhibit undefined behavior. – Igor Tandetnik Jul 06 '16 at 01:38
  • Please post a [MCVE](http://stackoverflow.com/help/mcve) – M.M Jul 06 '16 at 04:12
  • @IgorTandetnik https://github.com/vapourismo/luwra/blob/master/lib/luwra/usertypes.hpp#L145 – Ole Jul 06 '16 at 10:07
  • @M.M I've added the example. What do you intend to accomplish with it? – Ole Jul 06 '16 at 10:35
  • @Vapou compile and execute it and observe the behaviour you are claiming – M.M Jul 06 '16 at 13:39

0 Answers0