c++ - C++20 概念是否能够修复模板函数作为模板参数问题?

标签 c++ c++20 c++-concepts template-templates

如果你在 C++20 中尝试一些相对简单的东西,它会因 unhelpful error message spam 内爆。 .

int main() {
    auto as = std::vector{1,3,24,};
    auto bs = std::vector{1,4,10};
    auto cs = std::vector<float>{};
    std::ranges::transform(as, bs, std::back_inserter(cs), std::max);
    std::ranges::copy(cs, std::ostream_iterator<float>(std::cout, " "));
}

原因是 std::max 是模板函数,所以它不起作用。 通过将参数设置为 lambda 或创建一个小的辅助仿函数,可以轻松解决此问题。

但我想知道 C++ 概念是否可以用来告诉我们想要什么模板实例化? 例如,我们修改了一些 require 语句,该语句表示如果仿函数参数是模板,则该仿函数的模板参数必须与容器 value_type 匹配。

我怀疑这是可能的,因为我认为在模板重载解析和约束检查启动之前必须知道仿函数的确切类型,换句话说,从概念到调用点的信息没有“反向传播”。

但我不确定,所以我决定询问。

如果你想知道我尝试过什么,这是我的代码,但它非常糟糕,我无法编写模板模板参数代码......

但无论如何,我希望它能说明这个想法......

template<typename C, typename F>
struct xtransform
{
    xtransform(C& c, F f) : c_(c), f_(f){}
    void operator()(){
    }
    C c_;
    F f_;
};
template<typename C, template<typename> typename F, typename FArg>
requires requires {
    std::is_same_v<typename C::value_type, FArg>;
}
struct xtransform<C, F<FArg>>
{
    xtransform(C& c, F<FArg> f) : c_(c), f_(f){}
    void operator()(C& c, F<FArg> f){
    }
    C c_;
    F<FArg> f_;
};

最佳答案

没有。

std::max 命名模板函数。具有不完整模板参数列表的模板函数名称在重载决策期间将转换为函数。重载解析需要将函数名称转换为指向固定签名的指针,或者使用 () 进行调用。

概念没有帮助。

现在你可以使用一个旧的技巧;函数有一个重载,该重载在非推导上下文中接受函数指针。当我编写手动 std 类函数类型时,我添加了一个 R(*)(Args...) 重载,正是出于这个原因;当存在类型完全匹配的重载时,允许重载解析。

但这不是基于概念的。

关于c++ - C++20 概念是否能够修复模板函数作为模板参数问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66894267/

相关文章:

c++ - Eigen 与 QGenericMatrix

c++ - 为什么 std::set 和 set::map 的默认构造函数需要堆分配?

c++ - 如何在C++ 20中使用格式打印毫秒

c++ - 在自定义容器上使用范围算法

C++ 需要带有反向返回类型概念检查的表达式

c++ - ofstream << 运算符没有将正确的大小写入文件

python - OpenCV:用轮廓上的大多数点拟合椭圆(而不是最小二乘法)

C++ 安全高效地将 std::weak_ordering 转换为 int

c++ - 我怎样才能为唯一的类组合获得一致的、唯一的标识符?

C++ 类型特征的概念