1

我有以下包含模板函数的代码。当我使用第二个参数作为枚举调用此函数时:在某些情况下,它会找到模板专业化,而在某些情况下却没有。

我已经验证枚举在两种情况下都是相同的枚举(例如,没有重新定义)并且其他参数具有正确的值,我发现一个编译是使用 -Winline set 完成的(我还没有尝试更改它)还有什么看着?

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)
{
   ....
}
4

2 回答 2

2

对于初学者,通常不建议使用模板特化作为重载模板函数的一种方式。模板特化与函数重载的交互很差,并且在选择它们时有一些非常晦涩的规则,通常认为只提供常规函数重载比特化函数模板更好。

在这种情况下,我建议将您的课程更改为如下所示:

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++ 区分了枚举类型和 type int。尽管有多种方法可以在ints 和枚举类型之间进行转换,但它们并不是一回事,而且设计用于捕获ints 的重载也不能保证也能捕获枚举类型。你可能最好专门重载函数来处理枚举的情况。

于 2011-02-10T03:03:42.033 回答
0

不是一个尝试的答案,但想要发布的内容超出了评论的范围......

基本上,这显示了 GCC 3.4.6 的预期行为(枚举从不匹配 int 特化)。你用的是什么编译器?你真的能提供一个类似的、完整的程序来产生错误吗?

#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
于 2011-02-10T03:55:05.497 回答