"Тип является неполным" (но не является), и код компилируется


У меня есть шаблон класса

template<typename EventT, typename StateT, typename ActionT, 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>

Специализация используется для преобразования типа функции в типы возвращаемых значений и параметров.

Реализация класса работает, как и ожидалось, и все тесты пройдены.

Если я добавляю значение по умолчанию к ActionT, делая его ActionT = void(), Visual Studio жалуется на "тип StateMachine является неполным", и IntelliSense перестает работать (по крайней мере, для всех экземпляров этого типа). Однако ... код компилируется, и все тесты проходят точно так же, как и раньше (у меня есть также тест, который явно использует аргумент по умолчанию).

Это ошибка в Visual Studio или я что-то упустил?

Я использую VS 2015 Pro и C++ 14.

EDIT

Вот минимальный рабочий пример:

#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 выдает эту ошибку:

Для sm1 он находит функцию-член sayHello()...

Но не для sm2

Однако код компилируется и выдает следующий результат:

hello
7
hello world
hello

Что верно.

1 4

1 ответ:

Я, наконец, понял, что это проблема для ReSharper IntelliSense и все. Если я отключаю Resharper, код больше не подчеркивается. Я доложу об этом Джетбрейнсу и буду держать вас в курсе событий.

Edit

Корень всех зол-это подстановка типа функции в сигнатуру функции:

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

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

Обновить

Я открыл билет на YouTrack отслеживания (баг-трекере продуктами компании JetBrains) и разработчиком был назначен он.