了解 C++ 成员函数模板特化

2024-02-17

我有以下课程:

#pragma once
#include <string>
#include <iostream>

class testclass
{
public:
    template <class T> T item(const std::string& key)
    {
        std::cout << "non-specialized\n";
        return T();
    }
};

对于 item 方法,我想提供字符串的专业化。我尝试按以下方式执行此操作(在 testclass.cpp 中):

#include "testclass.h"
#include <iostream>

template<> std::string testclass::item(const std::string& key)
{
    std::cout << "specialized\n";
    return std::reverse(key.begin(), key.end());
}

然后我尝试像这样调用该函数:

#include <iostream>
#include "testclass.h"

int main()
{
    testclass t;
    std::string key = "foo";
    t.item<int>(key);
    std::string s = t.item<std::string>(key);
    std::cout << s << std::endl;
}

但是,输出是

$ ./a.out
non-specialized 
non-specialized
(empty line)

我所期望的是

$ ./a.out
non-specialized 
specialized
oof

我怎样才能正确地做到这一点?我正在使用 g++ 4.5.2 来编译该程序。

Edit:

解决方案是移动整个专业化的定义item到 testclass.h (但不进入类)。我在程序中还有其他错误,例如没有包括<algorithm>(用于反向),并错误地认为它会返回反向字符串。为了实现例外行为,.cpp 文件留空,标头内容如下:

#pragma once
#include <string>
#include <iostream>
#include <algorithm>

class testclass
{
    public:
        template <class T> T item(const std::string& key)
        {
            std::cout << "non-specialized\n";
            return T();
        }
};

template<> std::string testclass::item(const std::string& key)
{
    std::cout << "specialized\n";
    std::string s = key;
    std::reverse(s.begin(), s.end());
    return s;
}

问题归结为头文件中没有模板的常见问题。编译器在处理时main没有看到专业化,它生成自己的通用模板实例std::string。这违反了 ODR,因为现在有 2 个不同的专业化std::string在同一个程序中,但编译器不需要对其进行诊断。

简单的解决方案是在标头中声明/定义专业化,以便编译器可以使用它,或者至少知道在处理时不要从通用版本生成专业化main

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解 C++ 成员函数模板特化 的相关文章

随机推荐