c++ - Variadic templates with defaulted parameters -


first background. origin of question (and source of immense frustration me right now) i'm trying libc++ usable msvc. compiling library didn't prove tricky, getting templates compile is.

one big hurdle i've hit trying compile headers variadic templates enabled. specifically, in header there code templated __invoke functions (for generically invoking function types variadic parameters).

i've extracted of code provide stand alone snippet. myinvoke templates based on __invoke ones in libc++. comments in code explain what's going on (apologies, not small snippet!):

#include <type_traits>  using namespace std;  // declarations of myinvoke templates.  both of them designed take  // member function pointer _fp, class instance _a0 (which _fp assumed // point member of) , variadic list of arguments _fp.  // first 1 handles case _a0 instance of class // derived class _fp member of.  // second 1 handles case when _a0 pointer instance of  // class derived class _fp member of.  template <class _fp, class _a0, class ..._args, class = typename enable_if     <     is_member_function_pointer<typename remove_reference<_fp>::type>::value &&     is_base_of<typename remove_reference<typename __member_pointer_traits<typename remove_reference<_fp>::type>::_classtype>::type,     typename remove_reference<_a0>::type>::value     >::type > auto myinvoke(_fp&& __f, _a0&& __a0, _args&& ...__args) -> decltype((std::forward<_a0>(__a0).*__f)(std::forward<_args>(__args)...));  template <class _fp, class _a0, class ..._args, class = typename enable_if     <     is_member_function_pointer<typename remove_reference<_fp>::type>::value &&     !is_base_of<typename remove_reference<typename __member_pointer_traits<typename remove_reference<_fp>::type>::_classtype>::type,     typename remove_reference<_a0>::type>::value     >::type > auto myinvoke(_fp&& __f, _a0&& __a0, _args&& ...__args) -> decltype(((*std::forward<_a0>(__a0)).*__f)(std::forward<_args>(__args)...));   // definitions of myinvoke templates.    template <class _fp, class _a0, class ..._args, class> inline auto myinvoke(_fp&& __f, _a0&& __a0, _args&& ...__args)     -> decltype((std::forward<_a0>(__a0).*__f)(std::forward<_args>(__args)...)) {     return (std::forward<_a0>(__a0).*__f)(std::forward<_args>(__args)...); }  template <class _fp, class _a0, class ..._args, class> inline  auto myinvoke(_fp&& __f, _a0&& __a0, _args&& ...__args)     -> decltype(((*std::forward<_a0>(__a0)).*__f)(std::forward<_args>(__args)...)) {     return ((*std::forward<_a0>(__a0)).*__f)(std::forward<_args>(__args)...); }  // class member can create member fn pointer to. struct someclass {     typedef double(someclass::*foo_t)(int, float, double);     double foo(int a, float b, double c){return 0.0;} };  int main() {     someclass sc;     someclass::foo_t pfoo = &someclass::foo;      // invoke first template      myinvoke(pfoo, sc, 0, 0.0f, 0.0);      // invoke second template.     myinvoke(pfoo, &sc, 0, 0.0f, 0.0);      return 0; } 

this code compiles fine gcc, fails msvc (using either libc++ or msvc's type_traits header). i'll come onto error in moment, first need clear points on templating.

question 1:

can point me specific part of standard specification, specific documentation or give me official lingo trick of defaulting parameter after parameter pack.

question 2:

how compiler pick correct definition (implementation) of template? clear me how correct declaration chosen sfinae means 1 can work. however, definitions indistinguishable apart trailing return type. sfinae apply in scope of trailing return types? if that's case of course only 1 of decltype statements can compile 1 implementation applicable (in context of each myinvoke call). however, still strange (to me @ least) compiler need instanciate both definitions of template - 1 each call of myinvoke. each 1 have same signature return types same in both cases (although resolved in different way). mean compiler sees these 2 instances of template different? if so, can point me documentation of please?

onto msvc error

1>test.cpp(165): warning c4348: 'myinvoke' : redefinition of default parameter : parameter 4

1> test.cpp(162) : see declaration of 'myinvoke'

1>test.cpp(196): error c2995: 'unknown-type myinvoke(_fp &&,_a0 &&,_args &&...)' : function template has been defined

1> test.cpp(162) : see declaration of 'myinvoke'

1>test.cpp(211): error c3861: 'myinvoke': identifier not found

1>test.cpp(214): error c3861: 'myinvoke': identifier not found

(to appropriate line numbers match up, copy paste sample into: http://webcompiler.cloudapp.net/)

it's probable clear answer question 1 me solve problem but:

question 3:

what part of msvc non-conformance causing this? indeed non-conformance or possibly case gcc/clang support extensions language?

thanks in advance. i'm off coffee , pretend templates don't exist (this tip of iceberg in terms of "fun" i'm having!).


Comments

Popular posts from this blog

Magento/PHP - Get phones on all members in a customer group -

php - .htaccess mod_rewrite for dynamic url which has domain names -

Website Login Issue developed in magento -