You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++编译期实现无需两两比较的模板参数类型唯一性校验函数

实现正确性评估

你的实现逻辑在C++20及以上标准环境下基本成立,仅存在两处限制:

  • 依赖C20新增的constexpr虚函数特性,无法在C17及更低版本中编译
  • 未处理空参数包场景,当模板参数包Ts为空时,会因缺少B<>的特化定义触发编译错误
    其余场景下你的逻辑是通顺的:重复类型对应的虚函数会被最派生类的同签名函数覆盖,多次调用同一类型对应的f方法时会累加同一个count变量,超过1次就会标记类型重复,测试用例的运行结果也符合预期。

更简洁的实现方案

你可以利用多继承中重复基类导致的指针转换歧义来实现,不需要虚函数,完全编译期计算,无运行时开销,也符合「不得两两比较参数类型」的限制:

#include <type_traits>

template<typename T> struct Tag {};
template<typename... Ts> struct Checker : Tag<Ts>... {};

template<typename T, typename... Ts>
constexpr bool has_unique_tag = requires(Checker<Ts...> c) {
    static_cast<Tag<T>*>(&c);
};

template<typename... Ts>
constexpr bool allTypesUnique() {
    if constexpr (sizeof...(Ts) == 0) {
        return true;
    }
    return (... && has_unique_tag<Ts, Ts...>);
}

// 测试用例
int main() {
    static_assert(allTypesUnique<>());
    static_assert(allTypesUnique<void>());
    static_assert(allTypesUnique<void, int&>());
    static_assert(!allTypesUnique<int&, int&>());
    static_assert(allTypesUnique<char, short, int>());
    static_assert(!allTypesUnique<char, short, char>());
}

实现逻辑说明

如果模板参数中存在重复类型,Checker会重复继承同一个Tag<T>实例,此时尝试将Checker实例指针转换为Tag<T>*会出现歧义,requires表达式返回false,最终折叠表达式返回false。空参数包默认返回true,符合零个类型互不重复的预期。

内容的提问来源于stack exchange,提问作者Fedor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 04:42:01