c++偏特化模板实现

 

背景

在c++模板使用过程中,偶尔可能会出现一些特殊的情况,有些特定的类型,需要跟通用逻辑不一样的处理,或者需要其他的处理。 当然这种情况下,单纯靠模板进行处理并不是最优解,但是今天讨论的是如何在这种情况下实现某些特定类型的区别实现。 有一部分是按模板类型来处理,有一部分是确定的类型来处理,这种情况我在网上搜了一下,似乎叫做偏特化模板。

实现

比较丑陋的实现方法

#include <iostream>
#include <sstream>
#include <typeinfo>
#include <cxxabi.h>

class Test {
public:
    template <typename T>
    void SetValue(const T& value) {
        std::stringstream ss("");
        // 获取模板变量的实际类型名称 进行特定逻辑判断
        std::string type_name = abi::__cxa_demangle(typeid(value).name(), NULL, NULL, NULL);
        if (type_name == "int") {
            ss << "int_value [" << value << "]";
        } else {
            ss << value;
        }
        message_ = ss.str();
        std::cout << "message is: " << message_ << std::endl;
    }
    
private:
    std::string message_;
};

int main(int argc, char** argv) {
    Test test;
    test.SetValue(1);
    test.SetValue(2.2);
    test.SetValue("test");
    return 0;
}
运行结果:
message is: int_value [1]
message is: 2.2
message is: test

本次要讲的实现方法

#include <iostream>
#include <sstream>

class Test {
public:
    // 实现写在类外面是为了避免g++编译报错:
    // explicit specialization in non-namespace scope
    template <typename T>
    void SetValue(const T& value);
    
private:
    std::string message_;
};

// 写成内联函数是为了当这个类在头文件中被定义并且被多次引用时,避免出现二义性
template <typename T>
inline void Test::SetValue(const T& value) {
    std::stringstream ss("");
    ss << value;
    message_ = ss.str();
    std::cout << "message is: " << message_ << std::endl;
}

template <>
inline void Test::SetValue(const int& value) {
    std::stringstream ss("");
    ss << "int_value [" << value << "]";
    message_ = ss.str();
    std::cout << "message is: " << message_ << std::endl;
}

int main(int argc, char** argv) {
    Test test;
    test.SetValue(1);
    test.SetValue(2.2);
    test.SetValue("test");
    return 0;
}
运行结果:
message is: int_value [1]
message is: 2.2
message is: test