Summary: | [C++0x] substitution failure reports error with result_of | ||
---|---|---|---|
Product: | gcc | Reporter: | Jarryd Beck <jarro.2783> |
Component: | c++ | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED INVALID | ||
Severity: | normal | CC: | daniel.kruegler |
Priority: | P3 | ||
Version: | 4.7.0 | ||
Target Milestone: | --- | ||
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: | ||
Attachments: | substitution failure error |
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. 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 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> auto 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]; Array() { 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 auto 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); } 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 (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 Ok, I guess we can close this. |
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. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/home/jarrydb/current/soft/install-latest/libexec/gcc/x86_64-unknown-linux-gnu/4.7.0/lto-wrapper 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)