http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54111
--- Comment #5 from Leonid Volnitsky <leonid at volnitsky dot com> 2012-08-15 17:34:41 UTC --- More combinatorics and more test (gcc-trunk, clang-trunk and gcc463). Now everything in one file. ----------------------------------------------------------------- #include <tuple> #include <utility> using namespace std; int& plaint_f( int& x) {return x;}; const int& plaint_f(const int& x) {return x;}; template<class T, class R> R eval (T& x, R& (*f)(T&)) { return (*f)(x); }; template<class T, class R> R eval_const (const T& x, const R& (*f)(const T&)) { return (*f)(x); }; template<class T, class R=int> R eval_tuple_int (T& x, R& (*f)(T&)) { return (*f)(x); }; template<class T, class R=int> R eval_tuple_int_const (T& x, const R& (*f)(const T&)) { return (*f)(x); }; template<class ...Ts, class R> R eval_tuple (tuple<Ts...>& x, R& (*f)(tuple<Ts...>&)) { return (*f)(x); }; template<class ...Ts, class R=int> R eval_tuple_int (tuple<Ts...>& x, R& (*f)(tuple<Ts...>&)) { return (*f)(x); }; template<class ...Ts, class R> R eval_tuple_const (const tuple<Ts...>& x, R& (*f)(const tuple<Ts...>&)) { return (*f)(x); }; template<class ...Ts, class R=int> R eval_tuple_const_int (const tuple<Ts...>& x, R& (*f)(const tuple<Ts...>&)) { return (*f)(x); }; int main() { // int i42=42; // return eval(i42, plaint_f); // OK // 20.4.2.6 GET<..>(TUPLE) // // template <size_t I, class... Types> // typename tuple_element<I, tuple<Types...> >::type& get(tuple<Types...>&) noexcept; // // template <size_t I, class... types> // typename tuple_element<I, tuple<Types...> >::type&& get(tuple<Types...>&&) noexcept; // // template <size_t I, class... types> // typename tuple_element<I, tuple<Types...> >::type const& get(const tuple<Types...>&) noexcept; tuple<int,int> tpl(42,43); ////// INT eval..(TUPLE) // return eval_tuple_int(tpl, get<0,int,int>); // gcc48-ERROR types ‘tuple<_Elements ...>’ and ‘const pair<int, int>’ have incompatible cv-qualifiers // gcc46-OK // clang-OK // return eval_tuple_int(tpl, get<0>); // gcc48-OK // gcc46-OK // clang-OK // return eval_tuple_int_const(tpl, get<0,int,int>); // gcc48-OK // gcc46-OK // clang-OK // return eval_tuple_int_const(tpl, get<0>); // gcc48-OK // gcc46-OK // clang-OK ////// eval(TUPLE) // return eval(tpl, get<0>); // gcc48-ERROR couldn't deduce template parameter ‘R’ // gcc46-ERROR // clang-ERROR couldn't infer template argument 'R' // return eval(tpl, get<0,int,int>); // gcc48-ERROR could not resolve address from overloaded function ‘get<0, int, int>’ // gcc46-OK // clang-ERROR couldn't infer template argument 'R' // return eval_const(tpl, get<0>); // gcc48-ERROR couldn't deduce template parameter ‘R’ // gcc46-ERROR // clang-ERROR couldn't infer template argument 'R' // return eval_const(tpl, get<0,int,int>); // gcc48-OK // gcc46-OK // clang-ERROR couldn't infer template argument 'R' ////// eval_tuple..(TUPLE) // return eval_tuple(tpl, get<0,int,int>); // gcc48-ERROR types ‘tuple<_Elements ...>’ and ‘const tuple<int, int>’ have incompatible cv-qualifiers // gcc46-OK // clang-OK // return eval_tuple_const(tpl, get<0,int,int>); // gcc48-OK // gcc46-OK // clang-OK // return eval_tuple_const(tpl, get<0>); // gcc48-ERROR couldn't deduce template parameter ‘R’ // gcc46-ERROR // clang-ERROR }