将类型特征从实现中定义

Decoupling type traits definition from implementation

本文关键字:定义 实现 类型 特征      更新时间:2023-10-16

让我们考虑以下类,该类检查提供的类型是字符串,并使用类型特征根据结果调用不同的函数。原始源具有对OBJ的类型依赖性,这是一个简化的示例:

template <typename Obj> 
class example {
    public:            
        template <bool IdIsString = std::is_same<std::string, Obj>::value>
        typename std::enable_if<IdIsString, void>::type
        doStuff() {
            this->object->doSomething();
        }
        template <bool IdIsString = std::is_same<std::string, Obj>::value>
        typename std::enable_if<!IdIsString, void>::type
        doStuff()  {
            this->object->doSomethingElse();
        }
     private:
        AnyObject object;
};

我将如何从类中解除定义(例如将其存储在example_inline.hpp中),而无需在定义中提供每个类型的特征情况?

理想的解决方案看起来像这样:

// header.hpp
template <typename Obj> 
class example {
    public:
        void doStuff(); 
}
// header_inline.hpp
template <typename Obj>
template <bool IdIsString = std::is_same<std::string, Obj>::value>
typename std::enable_if<IdIsString, void>::type
example::doStuff() {
   // ...
}
// ...

以上显然是不可能的。一种解决方案是将类type_trait函数从类中解除并将其放入一个详细的名称空间中不是很优雅。

有一个很好的解决方案解决这个问题吗?我真的很想让所讨论的标题很容易读取,而不会用tons tons enable_if的杂物。

感谢您对此事的任何输入。

您可以根据std::is_same的返回值超载:

template<typename T>
class example
{
private:
    void doStuff(std::true_type)
    {
        obj->doSomething();
    }
    void doStuff(std::false_type)
    {
        obj->doSomethingElse();
    }
public:
    void doStuff()
    {
        doStuff(std::is_same<T, std::string>{});
    }
};

在这种简单的情况下,您也可以在类模板的模板参数上专门使用doStuff

#include <iostream>
#include <string>
template<class T>
struct example
{ void doStuff(); };
template<class T>
void example<T>::doStuff()
{ std::cout<<"defaultn"; }
template<>
void example<std::string>::doStuff()
{ std::cout<<"stringn"; }
int main()
{
    example<int>{}.doStuff();
    example<std::string>{}.doStuff();
}

实时示例