4

У меня есть шаблон класс«Тип неполна» (но это не так) и код компилирует

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() ...

но не для см2

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

hello 
7 
hello world 
hello 

что правильно.

+1

Пожалуйста, предоставьте [mcve]. – Barry

+0

Я не знаю, поможет ли это вам, но ваш код отлично работает на 'g ++' и' clang ++ ' – tforgione

+0

Он также работает на msvc. Я думаю, что это проблема с парсером IntelliSense. – Timo

ответ

2

Наконец-то я понял, что это проблема интеллисенса Ресарпера. Если я отключу Resharper, код больше не будет подчеркиваться. Я сообщу об этом JetBrains и буду поддерживать вас в курсе событий.

Редактировать

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

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

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

Update

Я открыл билет на youtrack (JetBrain-х трекер), и разработчик был назначен ему.