Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why passing T from outer template as default argument to std::function causes compilation error?

I create a template class, and pass the T as a default type argument. However this causes compilation failure. Anyone can explain what happens? Thank you!

PS. The compiler I use is VS2012.

#include <functional>

using namespace std;

template <typename T = void()>
struct delegate
{
    typedef function<T> function_t;

    function_t f;
};

int main()
{
    delegate<> d;

    return 0;
}

Compiler outputs:

1>.\Microsoft Visual Studio 11.0\VC\include\functional(554): error C2027: use of undefined type 'std::_Get_function_impl<_Tx>'
1>          with
1>          [
1>              _Tx=void (__cdecl *)(void)
1>          ]
1>          test.cpp(12) : see reference to class template instantiation 'std::function<_Fty>' being compiled
1>          with
1>          [
1>              _Fty=void (__cdecl *)(void)
1>          ]
1>          test.cpp(17) : see reference to class template instantiation 'delegate<>' being compiled
1>.\Microsoft Visual Studio 11.0\VC\include\functional(555): error C2504: 'type' : base class undefined
1>.\Microsoft Visual Studio 11.0\VC\include\functional(558): error C2027: use of undefined type 'std::_Get_function_impl<_Tx>'
1>          with
1>          [
1>              _Tx=void (__cdecl *)(void)
1>          ]
1>.\Microsoft Visual Studio 11.0\VC\include\functional(558): error C2146: syntax error : missing ';' before identifier '_Mybase'
1>.\Microsoft Visual Studio 11.0\VC\include\functional(558): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
like image 561
Xin Huang Avatar asked Apr 15 '13 03:04

Xin Huang


1 Answers

As indicated by the comments on your question: This is just a bug in Visual Studio, not anything wrong with your C++ code. @Stephan-T-Lavavej says he's filed it as DevDiv#671343.

Assuming @Yakk's diagnosis is correct (MSVC incorrectly treating T as void(*)() instead of void()), I formerly proposed the "possible workaround" of

typedef function<typename remove_pointer<T>::type> function_t;

but as @JoshPeterson commented below, the bug still occurs in VS2013 even with that change, so it's not actually a workaround.

like image 173
Quuxplusone Avatar answered Sep 23 '22 03:09

Quuxplusone