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

将可变参数类型展开到另一类型的跨编译器兼容实现问题

问题解答

首先明确:这确实是MSVC的一个已确认bug,你联系团队后他们正在处理是正确的——MSVC在处理void_t展开可变参数的SFINAE场景时存在逻辑缺陷,没有正确检查每个ReturnsType特化的有效性,而GCC和Clang的实现符合C++标准要求。

兼容所有编译器的替代实现

你可以绕过void_t的问题,改用两种更可靠的方式实现AllReturnsType:

方式1:C++17及以上推荐——折叠表达式

利用C++17引入的折叠表达式直接对每个函数的返回类型做逻辑与判断,代码简洁且兼容性好:

#include <type_traits>
#include <utility>

template<typename TReturn, typename TFunction>
using ReturnsType = std::enable_if_t<std::is_same_v<decltype(std::declval<TFunction>()()), TReturn>>;

// 兼容所有主流编译器的AllReturnsType
template<typename TReturn, typename... TFunctions>
using AllReturnsType = std::enable_if_t<(std::is_same_v<decltype(std::declval<TFunctions>()()), TReturn> && ...)>;

方式2:C11/C14兼容——使用conjunction trait

如果需要兼容更早的C标准,可以借助std::conjunction(C14引入,若编译器不支持可自行实现类似的逻辑与模板):

#include <type_traits>
#include <utility>

template<typename TReturn, typename TFunction>
using ReturnsType = std::enable_if_t<std::is_same<decltype(std::declval<TFunction>()()), TReturn>::value>;

// 辅助结构体,递归判断所有函数返回类型
template<typename TReturn, typename... TFunctions>
struct AllReturnsTypeHelper : std::conjunction<std::is_same<decltype(std::declval<TFunctions>()()), TReturn>...> {};

// 对外暴露的别名模板
template<typename TReturn, typename... TFunctions>
using AllReturnsType = std::enable_if_t<AllReturnsTypeHelper<TReturn, TFunctions...>::value>;

测试验证

你可以用以下代码验证逻辑正确性:

// 测试函数
int foo() { return 42; }
int bar() { return 123; }
float baz() { return 3.14f; }

// 仅当所有传入函数都返回int时才匹配的模板
template<typename... Fns>
void check_all_int(AllReturnsType<int, Fns...>*) {}

int main() {
    // 编译通过:两个函数都返回int
    check_all_int<int(*)(), int(*)()>(nullptr);
    
    // 编译失败:baz返回float,不符合要求(注释掉可看到错误)
    // check_all_int<int(*)(), float(*)()>(nullptr);
    
    return 0;
}

关于MSVC的bug

正如你所说,这个问题已经被MSVC团队确认并进入处理流程,后续的编译器更新应该会修复void_t在可变参数展开场景下的SFINAE问题。在此之前,上述替代实现可以保证代码在VC++、GCC、Clang中都正常工作。

内容的提问来源于stack exchange,提问作者Ivan Sanz Carasa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:42:31