Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Type is incomplete" (but isn't) and code compiles

I have a template class

template<typename EventT, typename StateT, typename ActionT, bool InjectEvent = false, bool InjectStates = false, bool InjectMachine = false>
class StateMachine;

and a specialization of it

template<typename EventT, typename StateT, typename ActionResultT, typename ...ActionArgsT, bool InjectEvent, bool InjectStates, bool InjectMachine>
class StateMachine<EventT, StateT, ActionResultT(ActionArgsT...), InjectEvent, InjectStates, InjectMachine>

The specialization is used to resolve the function type to its return- and parameter types.

The implementation of the class works as expected and all tests are passed.

If I add a default value to ActionT by making it ActionT = void(), Visual Studio complains about "type StateMachine<...> is incomplete" and IntelliSense stops working (at least for all instances of this type). However the code compiles and all tests are passed just like before (I have also a test that explicit uses the default argument).

Is this a bug in Visual Studio or do I miss something?

I'm using VS 2015 Pro and C++ 14.

EDIT

Here is a minimal working example:

#include <iostream>
#include <functional>

using namespace std;

template<typename EventT, typename StateT, typename ActionT = void(), bool InjectEvent = false, bool InjectStates = false, bool InjectMachine = false>
class StateMachine;

template<typename EventT, typename StateT, typename ActionResultT, typename ...ActionArgsT, bool InjectEvent, bool InjectStates, bool InjectMachine>
class StateMachine<EventT, StateT, ActionResultT(ActionArgsT...), InjectEvent, InjectStates, InjectMachine>
{
public:
    typedef ActionResultT ActionT(ActionArgsT...);

    StateMachine(ActionT&& action) : _action(action)
    {        
    }

    ActionResultT operator()(ActionArgsT... args)
    {
        return _action(args...);
    }

    void sayHello() const
    {
        cout << "hello" << endl;
    }

private:
    function<ActionT> _action;
};

int sum(int a, int b)
{
    return a + b;
}

void print()
{
    cout << "hello world" << endl;
}

void main()
{
    StateMachine<string, int, int(int, int)> sm1(sum);
    sm1.sayHello();
    cout << sm1(2, 5) << endl;
    StateMachine<string, int> sm2(print);
    sm2();
    sm2.sayHello();
    getchar();
}

IntelliSense throws this error:

For sm1 it finds the member function sayHello()...

but not for sm2

However the code compiles and produces this output:

hello
7
hello world
hello

which is correct.

like image 968
Timo Avatar asked Feb 14 '17 18:02

Timo


1 Answers

I finally figured out that this is a problem of Resharper's intellisense. If I disable Resharper the code is not underlined anymore. I will report this to JetBrains and keep you up to date.

Edit

The root of all evil is the substitution of the function type into the function signature:

template<typename FT = void()>
struct Func;

template<typename FR, typename ...FArgs>
struct Func<FR(FArgs...)>
{
    // ...
}

Update

I opened a ticket on youtrack (JetBrain's issue tracker) and a developer has been assigned to it.

like image 185
Timo Avatar answered Oct 09 '22 23:10

Timo