Bug 50711 - [C++0x] substitution failure reports error with result_of
Summary: [C++0x] substitution failure reports error with result_of
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2011-10-13 02:00 UTC by Jarryd Beck
Modified: 2011-10-13 09:33 UTC (History)
1 user (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: x86_64-unknown-linux-gnu
Build: x86_64-unknown-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:

substitution failure error (7.96 KB, application/octet-stream)
2011-10-13 02:00 UTC, Jarryd Beck

Note You need to log in before you can comment on or make changes to this bug.
Description Jarryd Beck 2011-10-13 02:00:44 UTC
Created attachment 25479 [details]
substitution failure error

The attached file produces an error. I believe that the templated "get" function should fail, leaving the non templated function as the only valid choice, not reporting an error, but choosing the non templated function.

Compiled with:
g++ substitution.cpp -std=gnu++0x -save-temps

gcc -v

Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: /home/jarrydb/current/soft/src/gcc-git/configure --prefix=/home/jarrydb/current/soft/install-latest --disable-multilib --enable-languages=c,c++
Thread model: posix
gcc version 4.7.0 20111011 (experimental) (GCC)
Comment 1 Paolo Carlini 2011-10-13 02:15:42 UTC
Unfortunately, I don't think you can use std::result_of for sfinae purposes, if I understand correctly it's a well know annoyance which you have to overcome by open coding with std::declval.
Comment 2 Paolo Carlini 2011-10-13 02:19:27 UTC
Eg, if you simply open the <functional> header you will find plenty of decltype( std::declval... for sfinae, which cannot be replaced by a concise std::result_of
Comment 3 Jarryd Beck 2011-10-13 03:32:05 UTC
The following code works:

struct Tuple
  int a, b, c;

struct array_get
  template <typename T>
  const T&
  operator()(const T& t)
    return t;

  template <typename Array, typename First, typename... Location>
  operator()(const Array& a, First f, Location... loc)
  //  -> typename std::result_of<array_get(decltype(a[f]), Location...)>::type
    -> decltype(operator()(a[f], loc...))
    return operator()(a[f], loc...);

struct Array
  int array[5][5][5];

    for (int i = 0; i != 5*5*5; ++i)
      reinterpret_cast<int*>(array)[i] = i;

  int get(const Tuple& t)
    return array[t.a][t.b][t.c];

  template <typename... Location>
  //typename std::result_of<array_get(int[5][5][5], Location...)>::type
  get(Location... loc)
    -> decltype(array_get()(array, loc...))
    return array_get()(array, loc...);

int main(int argc, char *argv[])
  Array a;
  Tuple t{3,4,1};
  //return a.get(1,2,3);
  return a.get(t);
Comment 4 Jonathan Wakely 2011-10-13 08:18:07 UTC
See http://lwg.github.com/issues/lwg-defects.html#1225 and also 1270

result_of cannot be used for SFINAE, it requires that its arguments be a valid expression
Comment 5 Jonathan Wakely 2011-10-13 08:19:28 UTC
(In reply to comment #4)
> result_of cannot be used for SFINAE, it requires that its arguments be a valid
> expression

Should read: it requires that its arguments can form a valid expression
Comment 6 Paolo Carlini 2011-10-13 09:33:50 UTC
Ok, I guess we can close this.