public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/51710] New: decltype and SFINAE
@ 2011-12-30  3:47 solodon at mail dot com
  2011-12-30 13:10 ` [Bug c++/51710] " redi at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: solodon at mail dot com @ 2011-12-30  3:47 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51710

             Bug #: 51710
           Summary: decltype and SFINAE
    Classification: Unclassified
           Product: gcc
           Version: 4.6.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: solodon@mail.com


Hi,

I think the following code is well formed, but it fails to compile in g++ 4.6.1
and 4.5.2 (those that I had available). The code compiles in MS Visual C++
2010.

The problem is that decltype(foo(e1,e2)) in the result_type of enable_if below
fails the compilation instead of SFINAE.

#include <string>

/// Some meta-predicate on two types
template <typename E1, typename E2>
struct some_condition
{
    enum { value = false }; // Change to true to see it compile
};

/// Class can only be instantiated when some_condition<E1,E2>::value is true
template <typename E1, typename E2>
struct some_result_type
{
    /// Just an expression that will only compile when E1 and E2 are such
    int m[0-!some_condition<E1,E2>::value];            
};

/// This function doesn't have enable_if on it because 
/// I will only call it on the right types
template <typename E1, typename E2> 
some_result_type<E1,E2> foo(E1&& e1, E2&& e2)
{
    return some_result_type<E1,E2>();
} 

/// operator+ is overloaded for E1,E2 satisfying some_condition only
template <typename E1, typename E2> 
inline auto operator+(E1&& e1, E2&& e2) 
        -> typename std::enable_if<
               some_condition<E1,E2>::value, // We check condition
               decltype(foo(e1,e2)) // but this part fails the compilation
           >::type 
{ 
    return foo(std::forward<E1>(e1),std::forward<E2>(e2)); 
}

std::string my() { return "a"; }

void foo() 
{
    // The operator+ above should be disabled on arguments of these types
    // and regular addition of strings should be picked 
    std::string result = "aaaaa" + my(); 
}

int main() { foo(); }

When I compile this program I get:

In instantiation of 'some_result_type<const char (&)[6], basic_string<char> >':
exp2.cpp: 53:39:   instantiated from here
exp2.cpp: 26:42: error: size of array is negative

My system is Windows 7 Professional, with g++ 4.6.1 coming from MinGW release
from 2011-11-18 and g++ 4.5.2 coming from an earlier MinGW release. Command
line used: g++.exe -Wall -m32 -time -O2 -std=c++0x -o "exp2" "exp2.cpp"

Thanks,
Yuriy


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c++/51710] decltype and SFINAE
  2011-12-30  3:47 [Bug c++/51710] New: decltype and SFINAE solodon at mail dot com
@ 2011-12-30 13:10 ` redi at gcc dot gnu.org
  2011-12-30 13:13 ` paolo.carlini at oracle dot com
  2012-01-02 21:36 ` solodon at mail dot com
  2 siblings, 0 replies; 4+ messages in thread
From: redi at gcc dot gnu.org @ 2011-12-30 13:10 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51710

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-12-30 12:53:27 UTC ---
I think the code is invalid because the expression decltype(foo(e1,e2)) does
not occur in the "immediate context" of the function type

It works if you replace enable_if<cond, decltype(expr)> with
enable_if_foo<cond, type> where enable_if_foo evaluates decltype(expr)

template<bool, typename E1, typename E2>
struct enable_if_foo
{
  typedef decltype(foo(std::declval<E1>(), std::declval<E2>())) type;
};

template<typename E1, typename E2>
struct enable_if_foo<false, E1, E2>
{ };

/// operator+ is overloaded for E1,E2 satisfying some_condition only
template <typename E1, typename E2>
inline auto operator+(E1&& e1, E2&& e2)
        -> typename enable_if_foo<
               some_condition<E1,E2>::value, // We check condition
               E1, E2
           >::type
{
    return foo(e1, e2);
}


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c++/51710] decltype and SFINAE
  2011-12-30  3:47 [Bug c++/51710] New: decltype and SFINAE solodon at mail dot com
  2011-12-30 13:10 ` [Bug c++/51710] " redi at gcc dot gnu.org
@ 2011-12-30 13:13 ` paolo.carlini at oracle dot com
  2012-01-02 21:36 ` solodon at mail dot com
  2 siblings, 0 replies; 4+ messages in thread
From: paolo.carlini at oracle dot com @ 2011-12-30 13:13 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51710

Paolo Carlini <paolo.carlini at oracle dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
                 CC|                            |paolo.carlini at oracle dot
                   |                            |com
         Resolution|                            |DUPLICATE

--- Comment #2 from Paolo Carlini <paolo.carlini at oracle dot com> 2011-12-30 13:12:03 UTC ---
I agree, I think we can resolve this.

*** This bug has been marked as a duplicate of bug 27527 ***


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c++/51710] decltype and SFINAE
  2011-12-30  3:47 [Bug c++/51710] New: decltype and SFINAE solodon at mail dot com
  2011-12-30 13:10 ` [Bug c++/51710] " redi at gcc dot gnu.org
  2011-12-30 13:13 ` paolo.carlini at oracle dot com
@ 2012-01-02 21:36 ` solodon at mail dot com
  2 siblings, 0 replies; 4+ messages in thread
From: solodon at mail dot com @ 2012-01-02 21:36 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51710

--- Comment #3 from Yuriy Solodkyy <solodon at mail dot com> 2012-01-02 21:35:56 UTC ---
Thank you, I am aware of the workaround and that is exactly what I do in my
code, however I think the current behavior is counter intuitive:

1. I get error message about instantiation that I have not made myself in the
code or expected to be made, but because compiler had failure during
substitution in decltype.

2. The error message is missing the instantiation context as in regular cases,
which made me wonder for a long time what exactly fails and why, especially
since Visual C++ was doing what I expected.

3. The purpose of decltype is now less clear as for each such case I cannot
just use decltype, but have to create a dedicated meta-function again, that
uses the decltype inside.

4. Once the concept based overloading is there, I expect the function be thrown
out of the overload set because the types don't match the concept emulated here
with condition. There won't be compilation error then and with this code I am
simply trying to emulate the concept-based overloading with tools i have today.

Thank you,
Yuriy


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-01-02 21:36 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-30  3:47 [Bug c++/51710] New: decltype and SFINAE solodon at mail dot com
2011-12-30 13:10 ` [Bug c++/51710] " redi at gcc dot gnu.org
2011-12-30 13:13 ` paolo.carlini at oracle dot com
2012-01-02 21:36 ` solodon at mail dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).