Skip to content

Commit

Permalink
Fix visitor to be able to return a reference (issue #39, thanks @ligfx)
Browse files Browse the repository at this point in the history
  • Loading branch information
martinmoene committed Apr 11, 2020
1 parent a0a1be0 commit ab1ffb3
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
6 changes: 4 additions & 2 deletions include/nonstd/variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1919,7 +1919,8 @@ struct VisitorApplicatorImpl<R, TX<VT> >
template< typename Visitor, typename T >
static R apply(Visitor const&, T)
{
return R();
// prevent default construction of a const reference, see issue #39:
std::terminate();
}
};

Expand Down Expand Up @@ -2106,7 +2107,8 @@ struct VisitorApplicator
case 14: return apply_visitor<14>(v, arg);
case 15: return apply_visitor<15>(v, arg);

default: return R();
// prevent default construction of a const reference, see issue #39:
default: std::terminate();
}
}

Expand Down
6 changes: 4 additions & 2 deletions template/variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1660,7 +1660,8 @@ struct VisitorApplicatorImpl<R, TX<VT> >
template< typename Visitor, typename T >
static R apply(Visitor const&, T)
{
return R();
// prevent default construction of a const reference, see issue #39:
std::terminate();
}
};

Expand Down Expand Up @@ -1734,7 +1735,8 @@ struct VisitorApplicator
{% for n in range(NumParams) -%}
case {{n}}: return apply_visitor<{{n}}>(v, arg);
{% endfor %}
default: return R();
// prevent default construction of a const reference, see issue #39:
default: std::terminate();
}
}

Expand Down
19 changes: 19 additions & 0 deletions test/variant.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1604,4 +1604,23 @@ CASE("max_index(): should not cause erroneous bad_variant_access in get()" "[.is
}
}

namespace issue_39 {

struct tag_t {};

struct myvisitor
{
const std::string& operator()(const int&) const { throw std::exception(); }
const std::string& operator()(const tag_t&) const { throw std::exception(); }
const std::string& operator()(const std::string& s) const { return s; }
};
}

CASE("visitor: Visitors can't return references, but they can with std::variant" "[.issue-39]")
{
using namespace issue_39;
nonstd::variant<int, tag_t, std::string> v("hello");
nonstd::visit( myvisitor(), v );
}

// end of file

0 comments on commit ab1ffb3

Please sign in to comment.