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

如何让IdentifierType的std::is_default_constructible结果与tuple一致?

问题描述

我定义了一个继承自std::tuple的模板类IdentifierType,尝试用std::is_default_constructible检查其默认构造能力,代码如下:

template<typename ... Args>
class IdentifierType: public std::tuple<Args...>
{
public:
   IdentifierType(Args... args) requires( sizeof...(Args) != 0 ) :std::tuple<Args...>( std::move(args)... )
   {}

   IdentifierType(std::tuple<Args...> tuple ):std::tuple<Args...>( std::move(tuple) )
   {}

   IdentifierType()
   {}

   IdentifierType(const IdentifierType&) = default;
   IdentifierType(IdentifierType&&) = default;
   IdentifierType& operator=(const IdentifierType& other) = default;
   IdentifierType& operator=(IdentifierType&& other) = default;

   IdentifierType(std::convertible_to<std::tuple<Args...>> auto&& identifier )
           : std::tuple<Args...>( std::forward<decltype(identifier)>(identifier) )
   {}
};


struct Reader
{
   int mId;
   Reader(int id):mId(id)
   {}
};


int main()
{
   std::cout << "Reader: " << std::is_default_constructible<Reader>::value << std::endl;
   std::cout << "tuple Reader: " << std::is_default_constructible<std::tuple<Reader>>::value << std::endl;
   std::cout << "IdentifierType Reader: " << std::is_default_constructible<IdentifierType<Reader>>::value << std::endl;
}

程序输出:

Reader: false
tuple Reader: false
IdentifierType Reader: true

最后一行输出为true是因为IdentifierType显式定义了默认构造函数。请问需要修改哪些地方,才能让std::is_default_constructible<IdentifierType>::value的结果与std::tuple的结果一致?


解决方案

要让IdentifierType的默认构造能力与std::tuple保持一致,只需修改默认构造函数的定义:

  1. 删除显式定义的空体默认构造函数:移除代码中的IdentifierType() {}这一行。
  2. 添加默认生成的默认构造函数:替换为IdentifierType() = default;。

修改后的IdentifierType类核心部分如下:

template<typename ... Args>
class IdentifierType: public std::tuple<Args...>
{
public:
   IdentifierType(Args... args) requires( sizeof...(Args) != 0 ) :std::tuple<Args...>( std::move(args)... )
   {}

   IdentifierType(std::tuple<Args...> tuple ):std::tuple<Args...>( std::move(tuple) )
   {}

   IdentifierType() = default; // 替换原空体默认构造函数

   IdentifierType(const IdentifierType&) = default;
   IdentifierType(IdentifierType&&) = default;
   IdentifierType& operator=(const IdentifierType& other) = default;
   IdentifierType& operator=(IdentifierType&& other) = default;

   IdentifierType(std::convertible_to<std::tuple<Args...>> auto&& identifier )
           : std::tuple<Args...>( std::forward<decltype(identifier)>(identifier) )
   {}
};

原理说明

  • 原代码中显式写的空体默认构造函数IdentifierType() {}会强制类拥有一个默认构造入口,即便基类std::tuple<Args...>无法默认构造,std::is_default_constructible也会返回true,但实际调用这个构造函数会触发编译错误。
  • 使用= default声明后,编译器会自动生成与基类行为绑定的默认构造逻辑:
    • 当std::tuple<Args...>支持默认构造(所有模板参数都能默认构造)时,IdentifierType的默认构造函数正常可用,std::is_default_constructible返回true;
    • 当std::tuple<Args...>不支持默认构造时,IdentifierType的默认构造函数会被编译器隐式删除,此时std::is_default_constructible返回false,完全匹配std::tuple的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 22:02:13