-1

I have a template

T template<typename T>undefined_behavior(void)
{
    throw;
    return T{};
}
template<typename T>
struct UBHandler
{
    const bool valid;
    T value;
    (operator T)()
    {if(valid)return value;return undefined_behavior<T>();}
};

This works when using rvalues but breaks when using rvalue references because—references aren't pointers and can't be constructed out of thin air.

error: member ‘... ::value’ is uninitialized reference

Before I wipe out all code relying on this and start over, is there a way to satisfy the compiler with some kind of null reference or magic uncorn—union thing?

Or something.

Undefined behavior welcome.

This should work because std::optional exists and std::optional has rvalue reverence overloads? sadness. Perhaps not, after reading previously asked questions. But it was proposed in 2014 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3982.html I have no idea how to interpret this into a solution.

What is std::optional doing to get away with this that I'm missing? Sadness.

I tried reading the following questions but I have no ideas.

haelmic
  • 541
  • 4
  • 18
  • 2
    Well, given the shown code seems to be ill-formed (and no self-respecting C++ compiler will want to do anything here), any reply would be pure speculation, since your exact situation is unclear. – Sam Varshavchik Dec 13 '20 at 01:06
  • @SamVarshavchik If I knew how to write a default constructor for null type it wouldn't be a question. `UBHandler{false,?}` what could I possibly pass as an argument? There is nothing that I have yet found. Maybe a global void thing? – haelmic Dec 13 '20 at 01:13
  • 1
    This has nothing to do with any constructor. Things like a missing semicolon, and referring to undeclared class names tend to throw a monkey wrench in asking questions here. – Sam Varshavchik Dec 13 '20 at 01:27
  • 1
    `is there a way to satisfy the compiler with some kind of null reference or magic uncorn—union thing?` So use a pointer? It's literally a reference that can be invalid by being a `nullopt`. – KamilCuk Dec 13 '20 at 02:01
  • @KamilCuk I saw nullopt in my search and skipped over it. Thank you for your attention. – haelmic Dec 13 '20 at 15:38

1 Answers1

1

Seems trivial to overload the type for references and write:

#include <stdexcept>

template<typename T>
struct UBHandler
{
    const bool valid;
    T value;
    operator T() {
        if (valid) return value;
        throw std::runtime_error("");
    }
};

template<typename T>
struct UBHandler<T&>
{
    T *const value;
    UBHandler() : value(nullptr) {}
    UBHandler(T& value) : value(&value) {}
    operator T() {
        if (value) return *value;
        throw std::runtime_error("");
    }
};

int main() {
    UBHandler<int&> a;
    a + 1;
    int b = 1;
    int &c = b;
    UBHandler<int&> d{c};
    d + 1;
}
KamilCuk
  • 120,984
  • 8
  • 59
  • 111