gpt4 book ai didi

c++ - 强制类模板特化以提供一种或多种方法

转载 作者:行者123 更新时间:2023-12-05 01:52:05 25 4
gpt4 key购买 nike

我正在使用“特征”模式,其中我有一个表示为类模板的基本情况

template <class>
struct DoCache {
constexpr static bool value = false;
};

我希望用户专门针对他们的类型:

template <>
struct DoCache<MyType> {
constexpr static bool value = true;

static void write2Cache(MyType const&) { /* implementation */ }
static optional<MyType> readFromCache(string name) { /* implementation */ }
};

典型的用途是检索并将其用作:

// Define a variable template
template <class T>
constexpr bool do_cache_v = DoCache<T>::value;

// Use the above trait in compile time branching:
if constexpr (do_cache_v<T>)
{
write2Cache(arg);
}

这段代码有两个问题:

  1. 用户在专门化时只是间接地被迫提供一个“值”成员,更不用说使其成为正确的值(即 true)。我所说的间接是指他们会遇到一堆编译错误,只有事先知道答案才能解决这些错误。
  2. 没有办法“要求”他们创建两个需要的方法,即 write2CachereadFromCache,更不用说拥有(const)正确的类型了。

在一些代码库中,我已经看到通过定义生成器宏来解决上述注意事项,例如:

#define CACHABLE(Type, Writer, Reader) ...
  • 有更好的方法吗?
  • 能否使用概念来限制特化的外观?
  • 是否有兼容 C++17 的方式?

如能回答以上问题

最佳答案

C++17:奇怪的重复模板模式

这似乎是 CRTP 的合适用例:

template<typename T> 
struct DoCache {
void write2Cache() {
static_cast<T*>(this)->write2Cache();
}
// ...
};

template<typename T>
void write2Cache(DoCache<T>& t) {
t.write2Cache();
}

struct MyType : DoCache<MyType>
{
void write2Cache() { /* ... */ }
};

int main() {
MyType mt{};
write2Cache(mt);
}

不是要求客户专门化他们自己的类型的库类型,而是要求他们根据(静态多态性)库类型的契约/外观来实现他们自己的类型。


C++20:概念

有了概念,你可以完全跳过多态:

template<typename T>
concept DoCachable = requires(T t) {
t.write2Cache();
};

template<DoCachable T>
void write2Cache(T& t) {
t.write2Cache();
}

struct MyType {
void write2Cache() { /* ... */ }
};

struct MyBadType {};

int main() {
MyType mt{};
write2Cache(mt);

MyBadType mbt{};
write2Cache(mbt); // error: ...
// because 'MyBadType' does not satisfy 'DoCachable'
// because 't.write2Cache()' would be invalid: no member named 'write2Cache' in 'MyBadType'
}

然而,再次将要求放在客户端类型的定义站点上(与事后可以完成的特化相反)。


基于特征的条件调度到 write2Cache()

But how is the trait do_cache_v exposed this way?

C++17 方法

  • 由于基于 CRTP 的方法通过继承提供了“is-a”关系,您可以简单地实现“is-a DoCache<T>”的特征:

    #include <type_traits>

    template<typename>
    struct is_do_cacheable : std::false_type {};

    template<typename T>
    struct is_do_cacheable<DoCache<T>> : std::true_type {};

    template<typename T>
    constexpr bool is_do_cacheable_v{is_do_cacheable<T>::value};

    // ... elsewhere
    if constexpr(is_do_cacheable_v<T>) {
    write2Cache(t);
    }

C++20 方法

  • 有了概念,概念本身就可以作为特质:

    if constexpr(DoCachable<T>) {
    write2Cache(t);
    }

关于c++ - 强制类模板特化以提供一种或多种方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71781785/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com