C ++ необъяснимые варианты соответствия шаблонной функции перечислениям - PullRequest
1 голос
/ 10 февраля 2011

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

Я проверил, что перечисления являются одинаковыми перечислениями в обоих случаях (например, нет переопределений) и что другие параметры имеют правильные значения, я обнаружил, что одна компиляция выполняется с набором -Winline (я еще не пытался изменить его) на что еще посмотреть?

class A {
public:
    template <typename T>
    int f(uint32_t id, T const& t, bool cond);

    ...
};

template <typename T>
int A::f(uint32_t id, T const& t, bool cond)
{
   ...
}

template <>
inline int A::f<int>(uint32_t, int const& t, bool cond)
{
   ....
}

Ответы [ 2 ]

2 голосов
/ 10 февраля 2011

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

class A {
public:
    template <typename T>
        int f(uint32_t id, T const& t, bool cond);
    int f(uint32_t id, int t, bool cond);
    ...
};

Затем измените специализацию шаблона, чтобы он был просто реализацией перегрузки.Из-за способа, которым работает перегрузка функции C ++, это позволит более точно выбрать правильную версию функции.

Что касается вашего конкретного вопроса, причина того, что ваш код не всегда вызывает перегрузку, состоит в том, что C ++ делаетразличие между перечисляемым типом и типом int.Хотя существуют способы преобразования между int s и перечислимыми типами, они не одно и то же, и перегрузка, предназначенная для перехвата int s, также не гарантирует перехват перечислимых типов.Возможно, вам лучше перегрузить функцию, чтобы обработать перечислимый регистр.

0 голосов
/ 10 февраля 2011

Не является попыткой ответа, но вы хотите опубликовать больше, чем уместится в комментарии ...

По сути, это показывает ожидаемое поведение (перечисления никогда не совпадают с int specialization) для GCC 3.4.6.Какой компилятор вы используете?Можете ли вы предоставить аналогичную полную программу, которая выдает ошибку?

#include <iostream>                                                             

struct A                                                                        
{                                                                               
  public:                                                                       
    template <typename T>                                                       
    void f(const T&) { std::cout << "general\n"; }                              
};                                                                              

template <>                                                                     
void A::f<int>(const int&) { std::cout << "specialised\n"; }                    

enum E1 { Zero, One, Two };                                                     

enum E2 { Max = INT_MAX };                                                      

int main()                                                                      
{                                                                               
    A a;                                                                        
    a.f("abc");                                                                 
    a.f(123);                                                                   
    a.f(Zero);                                                                  
    E1 e = Two;                                                                 
    a.f(e);                                                                     
    a.f(Max);                                                                   
}

Вывод:

general
specialised
general
general
general
...