On 15/06/2013 10:59 p.m., Eric Niebler wrote:
>- Some specific uses of Proto actions in constant expressions fail. GCC
>reports an ambiguity with ref-qualifiers in the following scenario:
>
> struct foo
> {
> int& bar() &
> { return _bar; }
> //~ int&& bar() &&
> //~ { return static_cast<int&&>(_bar); }
> constexpr int const& bar() const &
> { return _bar; }
> constexpr int const&& bar() const &&
> { return static_cast<int const&&>(_bar); }
>
> int _bar;
> };
>
> foo().bar();
>
> For that to work correctly, the 4 overloads need to be provided.
Huh. According to the standard, or according to gcc? I won't work around
a bug in a compiler without filing it first.
I got a thorough explanation on the subject from this SO question:
http://stackoverflow.com/questions/17130607/overload-resolution-with-ref-qualifiers
. The answer confirms this is a GCC bug, and hints to a "better
workaround" that would retain constexpr functionality. I may pursue this
alternative workaround if I ever get to play with the constexpr side of
Proto v5 (that is, if I use it in a place other than next to an `omg` or
`srsly` identifier :P).
Another GCC bug (as far as I understand) is that instantiations within
template arguments to a template alias are completely ignored when the
aliased type does not depend on those, thus breaking SFINAE rules. I
have attached a small code sample that reproduces this issue.
Regards,
--
Agustín K-ballo Bergé.-
http://talesofcpp.fusionfenix.com
#include <iostream>
template<typename T>
struct void_template { typedef void type; };
template<typename T>
using void_template_alias = void;
template<typename T, typename U = void>
struct fun_template
{
void print() const
{
std::cout << "unspecialized" << std::endl;
}
};
template<typename T>
struct fun_template<T, typename void_template<typename T::type>::type>
{
void print() const
{
std::cout << "void" << std::endl;
}
};
template<typename T, typename U = void>
struct fun_template_alias
{
void print() const
{
std::cout << "unspecialized" << std::endl;
}
};
template<typename T>
struct fun_template_alias<T, void_template_alias<typename T::type>>
{
void print() const
{
std::cout << "void" << std::endl;
}
};
template<typename T>
struct hard_error
{
static_assert(sizeof(T) == 0, "Your expectations never hold");
};
template<typename T>
struct soft_error
{};
int main(int argc, char** argv)
{
// plain template, hard error case
// expected: compilation error
// GCC 4.8.1: compilation error
fun_template<hard_error<int>>{}.print();
// template alias, hard error case
// expected: compilation error
// GCC 4.8.1: "void"
fun_template_alias<hard_error<int>>{}.print();
// plain template, soft error case
// expected: "unspecialized"
// GCC 4.8.1: "unspecialized"
fun_template<soft_error<int>>{}.print();
// template alias, soft error case
// expected: "unspecialized"
// GCC 4.8.1: "void"
fun_template_alias<soft_error<int>>{}.print();
return 0;
}
_______________________________________________
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto