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

使用std::tuple<void>创建模板类shared_ptr时出现‘形成void引用’错误

问题分析与解决

你遇到的问题核心在于std::make_shared的实现会触发C<std::tuple<void>>的完整类型实例化,而部分编译器在处理std::conditional_t时,会意外实例化未被选中的分支(std::optional<std::tuple<void>>)。

当std::optional<std::tuple<void>>被实例化时,标准库的std::optional实现会尝试生成与模板参数相关的引用类型。虽然std::tuple<void>本身是合法类型,但部分标准库实现中,实例化std::optional<std::tuple<void>>会间接尝试创建void&类型(比如通过std::add_lvalue_reference_t),而C++禁止创建void的引用,因此触发编译错误。

而make_unique或直接声明C<std::tuple<void>>对象时,编译器不需要实例化C内部的ResultOptionalType别名(只有当这个别名被实际使用时才会触发实例化),因此不会触发错误。

解决方案

用模板特化替代std::conditional_t,完全避免未选中分支的实例化:

#include <memory>
#include <optional>
#include <tuple>
#include <variant>

template<typename Type>
class C {
public:
    using ResultOptionalType = std::optional<Type>;
};

// 针对std::tuple<void>的特化版本
template<>
class C<std::tuple<void>> {
public:
    using ResultOptionalType = std::monostate;
};

int main() {
    using ResultOptionalType = std::conditional_t<std::is_same_v<std::tuple<void>, std::tuple<void>>, std::monostate, std::optional<std::tuple<void>>>;
    using T = std::optional<std::tuple<void>>;

    C<std::tuple<void>> c1;
    auto c2 = std::make_unique<C<std::tuple<void>>>();
    auto c3 = std::make_shared<C<std::tuple<void>>>(); // 现在可正常编译
}

这个方案通过特化C类,让C<std::tuple<void>>的定义完全不涉及std::optional<std::tuple<void>>,从根源上避免了非法引用类型的生成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 09:29:50