当前位置: 首页 > 知识库问答 >
问题:

如何在局部特化模板类中实现完全特化模板成员函数

商璞
2023-03-14

假设我有一个模板类Foo,具有两个模板参数和一个模板成员函数。

我想在模板类是部分专门化的情况下进行成员函数专门化,但以下代码被g编译失败


    template <typename A, typename B>
    class Foo 
    {
    public:
        template<typename C> void bar();
    };
    
    template<> template<typename T> inline void Foo<T, int>::bar<float>() {
    }
    
    int main()
    {
        Foo<double, int> foo;
        foo.bar<float>();
    
        return 0;
    
    }

G说:

错误:在'

模板

我试过了

template<typename T> template<> inline void Foo<T, int>::bar<float>() {

而g抱怨更多

能不能可能,怎么做?

共有2个答案

龙俊英
2023-03-14

当你专门化你的类模板时,你已经得到了一个完全独立的专门化类。因此,你必须用函数foo来编写你的类规范。

例子:

template <typename A, typename B>
class Foo 
{
    public:
        template<typename C> void bar() { std::cout << "Generic" << std::endl;}
};

template <typename T>
class Foo<T,int>
{
    public:
        template<typename C> void bar(){ std::cout << "spezialized" << std::endl; }

};

int main()
{
    Foo<double, int> foo;
    foo.bar<float>();

    Foo<double, char> foo2;
    foo2.bar<int>();

    return 0;

}

我相信你会尝试做一些不同的事情:-)

如果您只想在特定的专门化中对成员进行专门化,而在非专门化的情况下,您希望看到类模板的通用功能,那么您可以这样做:

例子:

class Base
{
    public:
    template<typename C> void bar() { std::cout << "Generic" << std::endl;}
    void other() { std::cout << "Other" << std::endl; }
};

template <typename A, typename B>
class Foo: public Base
{
};

template <typename T>
class Foo<T,int>: public Base
{
    public:
        template<typename C> void bar(){ std::cout << "spezialized" << std::endl; }

};

int main()
{
    Foo<double, int> foo;
    foo.bar<float>();
    foo.other();

    Foo<double, char> foo2;
    foo2.bar<int>();
    foo2.other();

    return 0;
}
柳晔
2023-03-14

[温度说明规格]/17:

在类模板的成员或出现在命名空间作用域中的成员模板的显式专门化声明中,该成员模板及其某些封闭类模板可能仍然未被专门化,但如果其封闭类模板也未被显式专门化,则该声明不应显式专门化该类成员模板。在这种明确的专门化声明中,应提供关键字模板和模板参数列表,而不是模板

在类模板的成员或出现在命名空间范围中的成员模板的显式特化声明中,成员模板及其某些封闭类模板可能保持非特化,除非声明不应显式特化类成员模板,如果其封闭类模板也没有显式特化。

对于您的代码:

template<typename A, typename B>
class Foo{
public:
    template<typename C> void bar();
};
    
template<typename T> // for `Foo`
template<>           // for `bar`
inline void Foo<T, int>::bar<float>(){}
    
int main(){
    Foo<double, int> foo;
    foo.bar<float>();
    return 0;
}

它的格式不正确,因为bar是显式专用的,而Foo不是。

 类似资料:
  • 我有一个问题,我想在下面的代码中专门化模板类的模板成员函数。这个问题的答案是模板类成员函数的显式特化,这似乎表明它无法完成。这是正确的吗,如果是这样,我可以使用任何解决方法,以便在编译时通过内联inc函数进行扩展? 非常感谢! g吐槽道: test2.cpp:32:13: 错误: 非命名空间作用域中的显式专用化 'struct IdxIterator' test2.cpp:32:25: 错误: 非

  • 是否有人知道此显式特化是否有效: clang 主干 (12/3/2013) 给出以下错误: f:...\test.cpp:36:20: 错误: 从类 'O' 中出线定义 “Fun” 没有定义 1生成错误。 任何来自标准的支持参考来证明你的答案将不胜感激! 注意:我有点惊讶这是一个错误——我认为应该为任何以< code >开始实例化“Fun”的模板参数族选择专门化 这是一个叮当的错误还是我期望中的错

  • 我写了一个模板函数,它使用了另外两个模板函数(添加 在math_functions.cpp中,我对add有不同的专门化 我还编写了一个简单的测试程序: 这段代码编译时没有任何错误,但奇怪的是,当我调用mulvadd时,调用的函数是h文件中定义的默认模板,而不是cpp文件中的专用版本。发生这种情况的原因是什么?

  • 我试图在类型s. t上专门化一个类。它忽略了给定类型的恒定性。在这种情况下,该类型是一个模板模板参数: 上面的代码在GCC 4.8.4和clang 5.0(with-std=c 11)中都抱怨bar在与匹配FOFType模板参数化的类一起使用时未定义。即使我删除了sfinae参数,仍然无法找到特化。 这个问题的一个例子可以在这里找到:https://godbolt.org/g/Cjci9C.在上面

  • 我有以下模板方法: 但是我得到了那些奇怪的链接错误: /usr/lib/gcc/x86_64-redhat-linux/4.4。7/../../../../包括/c/4.4。7/例外:62:void MyStruct::readField(std::basic_istream)的多重定义 如何专门化此成员函数? 编辑 这种方法在以下方面起作用: 或者使用s或在类外使用