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

Reply via email to