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

C++17替代C++20 requires实现条件构造函数的方法

C++17 等效实现方案

C17 没有原生的 concepts/requires 约束语法,我们可以通过 SFINAE(替换失败非错)规则 + 标准库类型萃取(type traits) 实现完全一致的重载选择逻辑。首先先修正原C20示例代码的两处问题:

  • 第二个构造函数参数列表末尾多余的逗号,属于语法错误
  • data_t 定义的条件分支错误:原代码无论has_type<T>是否成立最终都返回T类型,会导致两个构造函数参数列表完全一致引发重定义,按照需求逻辑,当T存在嵌套type别名时,data_t应该是typename T::type

第一步:实现has_type类型检测特性

C20中通过requires表达式实现的嵌套类型检测,在C17中可以通过std::void_t配合模板偏特化实现:

#include <type_traits>

// 检测类型T是否存在嵌套别名type
template <typename T, typename = void>
struct has_type : std::false_type {};

template <typename T>
struct has_type<T, std::void_t<typename T::type>> : std::true_type {};

template <typename T>
constexpr bool has_type_v = has_type<T>::value;

第二步:实现someClass类逻辑

构造函数的条件约束通过std::enable_if_t实现:因为构造函数没有返回值,我们将SFINAE约束放在构造函数的默认模板参数位置,保证重载决议时只有满足条件的构造函数会被纳入候选集:

template <typename T>
class someClass {
public:
    // 修正后的data_t定义:有嵌套type时取T::type,否则取T本身
    using data_t = std::conditional_t<has_type_v<T>, typename T::type, T>;

    // 约束1:T为算术类型时启用该构造
    template <typename U = T, 
              std::enable_if_t<std::is_arithmetic_v<U> && !has_type_v<U>, int> = 0>
    constexpr someClass(U const& _a, U const& _b) 
        : a{_a}, b{_b} {}

    // 约束2:T存在嵌套type别名时启用该构造
    template <typename U = T, 
              std::enable_if_t<has_type_v<U>, int> = 0>
    constexpr someClass(data_t const& _a, data_t const& _b) 
        : a{_a}, b{_b} {}

private:
    const data_t a, b;
};

逻辑一致性说明

  • 当传入算术类型(int/float/double等)作为模板参数T时,has_type_v<T>为false,第二个构造函数会因SFINAE被排除在重载候选集外,自动匹配第一个构造
  • 当传入带嵌套type别名的结构体/类作为T时,std::is_arithmetic_v<T>为false,第一个构造函数被排除,自动匹配第二个构造
  • 如果传入的T既不是算术类型,也没有嵌套type别名,两个构造函数都不会进入候选集,实例化会直接报错,和原C++20代码行为完全一致

使用示例

// 测试用自定义类型
struct x { using type = float; };

int main() {
    // 匹配算术版本构造
    someClass<int> c1(1, 2);
    // 匹配带嵌套type版本构造,参数类型为float
    someClass<x> c2(1.5f, 2.5f);
    return 0;
}

内容的提问来源于stack exchange,提问作者Chris G.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:39:25