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

如何仅在模板类型含data和size成员函数时启用构造函数?

解决方案

C++20及以上(简洁方案)

利用C++20引入的requires约束,直接在模板构造函数上添加条件,确保传入的类型T拥有符合要求的data()和size()成员函数:

#include <concepts>

struct MyStructure {
  MyStructure(char* d, int size) {}

  template <typename T>
  requires requires(T&& rhs) {
      // 检查rhs有data()成员,且返回值可转换为char*
      { rhs.data() } -> std::convertible_to<char*>;
      // 检查rhs有size()成员,且返回值可转换为int
      { rhs.size() } -> std::convertible_to<int>;
  }
  MyStructure(T&& rhs) : MyStructure(rhs.data(), rhs.size()) {}
};

这里的双层requires是C++20的语法:外层用于约束模板的实例化,内层通过表达式验证确认类型具备所需成员函数,同时还能检查返回值的兼容性。

C11/C17兼容方案

借助SFINAE(替换失败并非错误)机制,结合std::enable_if和类型特性(trait)实现条件启用:

基础版本(仅检查成员存在)

#include <type_traits>

// 定义类型特性,判断T是否拥有data()和size()成员
template <typename T, typename = void>
struct has_data_and_size : std::false_type {};

template <typename T>
struct has_data_and_size<T, std::void_t<
    decltype(std::declval<T>().data()),
    decltype(std::declval<T>().size())
>> : std::true_type {};

struct MyStructure {
  MyStructure(char* d, int size) {}

  // 仅当has_data_and_size<T>::value为true时,此构造函数才会被启用
  template <typename T, typename = std::enable_if_t<has_data_and_size<T>::value>>
  MyStructure(T&& rhs) : MyStructure(rhs.data(), rhs.size()) {}
};

增强版本(同时检查返回值兼容性)

如果需要确保data()和size()的返回值能适配第一个构造函数的参数,可以扩展类型特性:

#include <type_traits>

template <typename T, typename = void>
struct has_valid_data_and_size : std::false_type {};

template <typename T>
struct has_valid_data_and_size<T, std::void_t<
    decltype(std::declval<T>().data()),
    decltype(std::declval<T>().size())
>> : std::conjunction<
    // 检查data()返回值可转换为char*
    std::is_convertible<decltype(std::declval<T>().data()), char*>,
    // 检查size()返回值可转换为int
    std::is_convertible<decltype(std::declval<T>().size()), int>
> {};

struct MyStructure {
  MyStructure(char* d, int size) {}

  template <typename T, typename = std::enable_if_t<has_valid_data_and_size<T>::value>>
  MyStructure(T&& rhs) : MyStructure(rhs.data(), rhs.size()) {}
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 22:42:08