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

为何common_type_t未生成预期通用类型?容器类型异常解析

问题:容器元素类型为何被认为是int而非从参数包推测的double?

请看以下代码:

#include <iostream>
#include <vector>

using namespace std;

template<template <class ...> class Container, typename ... Args>
Container<common_type_t<remove_cvref_t<Args> ...>> fn( Args &&... args );

int main()
{
    for( int i : fn<vector>( 1, 2.6, 3 ) )
        cout << i << ", " << endl;
    // 输出正确类型...
    cout << typeid(common_type_t<int, double>).name() << endl;
}

template<template <class ...> class Container, typename ... Args>
Container<common_type_t<remove_cvref_t<Args> ...>> fn( Args &&... args )
{
    Container<common_type_t<remove_cvref_t<Args> ...>> cont;
    (cont.emplace_back( forward<Args>( args ) ), ...);
    return cont;
}

编译器对fn<>()的函数调用给出如下警告:

'initializing': conversion from '_Ty' to 'int', possible loss of data

原因解析

你误解了问题的根源:容器的元素类型实际上是double,而非int。

问题出在main函数的范围for循环里:

for( int i : fn<vector>( 1, 2.6, 3 ) )

这里的int i是你显式声明的循环变量类型,编译器需要把容器中存储的double类型元素转换为int,这才触发了“可能丢失数据”的警告。

验证这一点很简单:把循环变量类型改成auto或者double,警告就会消失,而且能看到正确的浮点数值:

for( auto i : fn<vector>( 1, 2.6, 3 ) )
    cout << i << ", " << endl;

另外,你代码里的typeid(common_type_t<int, double>).name()输出的确实是double,这也佐证了common_type_t<int, double, int>的结果是double——因为std::common_type会取所有类型的共同兼容类型,int和double的共同类型就是double。

额外说明

如果想确保容器元素类型是参数包中所有类型的共同类型,你的代码逻辑是正确的:remove_cvref_t用于剥离参数的引用和cv限定符,common_type_t推导所有类型的共同类型,最终容器的元素类型就是这个共同类型。问题只是出在循环时的变量类型声明上。


内容的提问来源于stack exchange,提问作者Edison von Myosotis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:55:02