c++ - 具有不同签名的类方法特化

标签 c++ templates template-specialization

我正在尝试编写一个类模板,其中方法签名根据模板参数而变化。我的目标是尽可能少地重复代码。考虑这个例子,首先是类声明:

// a.hxx
#ifndef A_HXX
#define A_HXX

template<typename T>
struct A
{
    void foo(T value) const;
    void bar() const;
};

#include <string>

#ifndef short_declaration
template<>
struct A<std::string>
{
    void foo(const std::string &value) const;
    void bar() const;
};
#else // short_declaration
template<>
struct A<std::string>
{
    void foo(const std::string &value) const;
};
#endif // short_declaration

#endif // A_HXX

现在是类定义:

// a_impl.hxx
#ifndef A_IMPL_HXX
#define A_IMPL_HXX

#include "a.hxx"
#include <iostream>
#include <typeinfo>

template<typename T>
void A<T>::foo(T value) const
{
    std::cout << "A<T=" << typeid(T).name() << ">::foo(" << value << ")"
        << std::endl;
}

template<typename T>
void A<T>::bar() const
{
    std::cout << "A<T=" << typeid(T).name() << ">::bar()" << std::endl;
}

void A<std::string>::foo(const std::string &value) const
{
    std::cout << "A<std::string>::foo(" << value << ")" << std::endl;
}

#ifndef skip_duplicates
void A<std::string>::bar() const
{
    std::cout << "A<std::string>::bar()" << std::endl;
}
#endif // skip_duplicates

#endif // A_IMPL_HXX

现在是一个测试程序:

// test.cxx

//#define skip_duplicates
//#define short_declaration
#include "a_impl.hxx"

int main(void)
{
    A<int>         obj1;
    A<std::string> obj2;
    int         value1(1);
    std::string value2("baz");

    obj1.foo(value1);
    obj1.bar();

    obj2.foo(value2);
    obj2.bar();

    return 0;
}

如果像这样编译,我会得到预期的输出(对于我的 typeid 的实现):

A<T=i>::foo(1)
A<T=i>::bar()
A<std::string>::foo(baz)
A<std::string>::bar()

但在我的示例中,我当然想要一种启用 skip_duplicates 甚至 short_declaration 的方法。有点similar question , ecatmur回答说需要给出完整的类,所以至少定义 short_declaration 是行不通的。

其他人如何处理使用可能将大对象作为参数的方法创建类模板的问题?

最佳答案

您可以将重复项提取到基类中:

template<typename T>
struct Base{
    void Bar()
    {
        std::cout << "A<T=" << typeid(T).name() << ">::bar()" << std::endl;
    }

protected:
    ~Base(){}
    template<typename U>
    void DoFoo(U value)
    {
        std::cout << "A<T=" << typeid(T).name() << ">::foo(" << value << ")"
        << std::endl;
    }
};

template<typename T>
struct A : Base<T> {
    void Foo(T value)
    {
        DoFoo(value);
    }
};

template<>
struct A<std::string> : Base<std::string> {
    void Foo(const std::string& value)
    {
        DoFoo(value);
    }
};

关于c++ - 具有不同签名的类方法特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13820160/

相关文章:

c++ - 使用 boost::shared_array

c++ - 通过 c++ pugixml 库检索 PCDATA xpath

c++ - haar 训练 OpenCV 断言失败

c++ - 专门化模板中的一些方法

c++ - 将 const char** 与模板特化结合使用

c++ - 在 Windows 上使用 MinGW 构建时,cmake FindBoost 找不到 Boost 库

templates - {{template "base"}} 和 {{template "base".}} 在 go-gin 中的区别

C++ 对象将模板化函数和参数保留为成员以便稍后调用

c++ - 以内部模板化 typedef 作为参数的模板化延迟初始化单例

c++ - const char指针模板特化