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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With