2016-12-29 1 views
0

Я пытаюсь реализовать класс Expression с 2 специализациями для арифметических типов. Это класс по умолчанию:Шаблон специализации с enable_if и is_arithmetic для класса

template<typename Left, typename Op, typename Right, typename std::enable_if<!std::is_arithmetic<Left>::value, Left>::type* = nullptr> 
class Expression { /* ... */ } 

И те две специализации:

template<typename Left, typename Op, typename Right, typename std::enable_if<std::is_arithmetic<Left>::value, Left>::type* = nullptr> 
class Expression { /* ... */ }; 

template<typename Left, typename Op, typename Right, typename std::enable_if<std::is_arithmetic<Right>::value, Right>::type* = nullptr> 
class Expression { /* ... */ }; 

Если я теперь скомпилировать мой код, я получаю эту ошибку:

Error C3855 'Expression': template parameter '__formal' is incompatible with the declaration Vector

Как я могу решить мою проблема с шаблонами и специализациями или фиктивными типами, как я их использовал.

+0

Пожалуйста, поделитесь минимальным примером кода, показывающим ту же ошибку. С предоставленной вами информацией трудно догадаться, что случилось. – paweldac

+1

Я не вижу параметр шаблона с именем '__formal' (который является зарезервированным идентификатором) или декларация с именем' Vector' в любом месте вашего примера кода. Пожалуйста, опубликуйте [mcve]. – Praetorian

ответ

2

У вас есть несколько шаблонов первичных классов, и они не могут быть заменены. У вас должен быть один первичный шаблон, за которым следуют несколько специализаций. Простой подход, чтобы сделать это по-другому:

template<typename Left, typename Op, typename Right, 
     int = std::is_arithmetic_v<Left> + 2 * std::is_arithmetic_v<Right>> 
class Expression; 

template <typename Left, typename Op, typename Right> 
class Expression<Left, Op, Right, 0> { 
    // base case 
}; 
template <typename Left, typename Op, typename Right> 
class Expression<Left, Op, Right, 1> { 
    // only the left operand is arithmetic 
}; 
template <typename Left, typename Op, typename Right> 
class Expression<Left, Op, Right, 2> { 
    // only the right operand is arithmetic 
}; 
template <typename Left, typename Op, typename Right> 
class Expression<Left, Op, Right, 3> { 
    // both operands are arithmetic 
}; 

Если у вас есть несколько случаев, которые могут быть обработаны вместе, вы можете сделать эти первичные шаблоны и только специализироваться оставшиеся частные случаи.

+0

Благодарим вас за ответ. Проблема с первичными случаями в нескольких очередях была проблемой! –