【问题标题】:Can C++ concepts operate on overload sets?C++ 概念可以在重载集上运行吗?
【发布时间】:2023-04-04 07:29:01
【问题描述】:

C++ 有一个令人讨厌的限制,即无法将重载函数传递给模板,例如 std::max can not be nicely used with std::transform

我想如果概念可以解决这个问题会很好,但在我的尝试中我遇到了同样的问题。看起来概念无法根据函数类型的谓词来约束模板。

Example:

#include <type_traits>
#include <iostream>
#include <boost/callable_traits/args.hpp>
namespace ct = boost::callable_traits;

template <typename Fn>
concept Fn1 =  std::tuple_size<ct::args_t<Fn>>::value == 1;

template <typename Fn>
concept Fn2 =  std::tuple_size<ct::args_t<Fn>>::value == 2;

template<Fn1 Fn>
auto make(Fn f){
    return 1;
}

template<Fn2  Fn>
auto make(Fn f){
    return 2;
}

auto fn(int a){
}

auto fn(int a, float b){
    return 2;
}

int main() {
    std::cout << make(fn) << std::endl;
    std::cout << make(fn) << std::endl;
}

注释:

  • 我知道这个问题的不同解决方案,这只是一个示例问题,专门询问是否可以用概念来完成。
  • 我知道仅在 arity 上进行调度是原始的,例如谓词还应该返回 bool 等。

【问题讨论】:

  • anyone 如何区分make(fn)make(fn)
  • @Caleth 您在询问可读性或编译器如何做到这一点?
  • @NoSenseEtAl:两者都有。在逐个令牌级别上,它们是相同的。因此,它们必须导致相同的调用。我的意思是......你希望发生什么其他
  • 啊,我减少了我的例子太多...... :) 最初我想将 fn 传递给工厂,该工厂使用来自重载集的成员 funs 创建一个结构......但同样的想法,那些成员fns 将从原始重载集中调用特定的 arity 函数(基于传递给结构成员 fn 的参数数量)...
  • @NoSenseEtAl 也许编辑问题是明智的?提出的问题毫无意义。

标签: c++ c++20 c++-concepts


【解决方案1】:

为了让语言考虑一个类型是否满足一个概念,C++ 必须首先推导出参数的类型并将其插入到模板函数中。这种推论不会发生,因为参数是代表具有多个重载的函数的名称。所以概念甚至没有机会发挥作用。

只要由重载函数名组成的表达式不能进行模板参数推导,你试图做的事情就行不通。

即使它确实有效,它仍然不会有效。在这个假设中,fn 满足 both 概念。虽然基于概念的重载是一件事,但它是基于比较原子约束以寻找相似之处以查看哪个更受约束的事情。但是它们的原子约束是不相关的(就 C++ 而言)。因此,两者都将被视为同样有效,因此概念重载将失败。

你只需要做其他人都会做的事情:创建一个 lambda。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-14
    • 1970-01-01
    • 1970-01-01
    • 2017-05-16
    相关资源
    最近更新 更多