C++ 概念可以对重载集进行操作吗?
Can C++ concepts operate on overload sets?
C++ 有一个令人讨厌的限制,即无法将重载函数传递给模板,例如 std::max can not be nicely used with std::transform.
我在想如果概念可以解决这个问题就好了,但在我的尝试中我遇到了同样的问题。看起来概念无法基于函数类型的谓词来约束模板。
#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 上调度是原始的,例如谓词也应该return
bool
等
为了让语言考虑一个类型是否满足一个概念,C++ 必须首先推导出参数的类型并将其插入到模板函数中。这种推论不会发生,因为参数是一个代表具有多个重载的函数的名称。所以概念甚至没有机会发挥作用。
只要由重载函数名称组成的表达式不能进行模板参数推导,您的尝试就无法工作。
即使它确实起作用,它仍然不起作用。在这个假设中,fn
满足 两个 概念。虽然基于概念的重载是一回事,但它是基于比较原子约束以寻找相似性以查看哪个更受约束的事情。但它们的原子约束是无关的(就 C++ 而言)。因此,两者都将被视为同样有效,因此概念重载将失败。
您将不得不做其他人所做的事情:创建一个 lambda。
C++ 有一个令人讨厌的限制,即无法将重载函数传递给模板,例如 std::max can not be nicely used with std::transform.
我在想如果概念可以解决这个问题就好了,但在我的尝试中我遇到了同样的问题。看起来概念无法基于函数类型的谓词来约束模板。
#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 上调度是原始的,例如谓词也应该return
bool
等
为了让语言考虑一个类型是否满足一个概念,C++ 必须首先推导出参数的类型并将其插入到模板函数中。这种推论不会发生,因为参数是一个代表具有多个重载的函数的名称。所以概念甚至没有机会发挥作用。
只要由重载函数名称组成的表达式不能进行模板参数推导,您的尝试就无法工作。
即使它确实起作用,它仍然不起作用。在这个假设中,fn
满足 两个 概念。虽然基于概念的重载是一回事,但它是基于比较原子约束以寻找相似性以查看哪个更受约束的事情。但它们的原子约束是无关的(就 C++ 而言)。因此,两者都将被视为同样有效,因此概念重载将失败。
您将不得不做其他人所做的事情:创建一个 lambda。