如何通过参数的某些性质而不是其确切类型来指定参数类型? 因此,我在C++中有如下功能: 无效打印向量(标准::向量v){ 对于(int i:v){ std::cout

如何通过参数的某些性质而不是其确切类型来指定参数类型? 因此,我在C++中有如下功能: 无效打印向量(标准::向量v){ 对于(int i:v){ std::cout,c++,typing,C++,Typing,您正在寻找的是: 模板 无效打印(常量和可打印){ 用于(常量自动和i:可编辑){ std::cout假设您可以访问C++20,这就是如何使用概念限制模板接受的类型: template <typename T> concept printable = requires(T t) { std::cout << t; }; template <std::ranges::range T> requires printable<std::ranges:

您正在寻找的是:

模板
无效打印(常量和可打印){
用于(常量自动和i:可编辑){

std::cout假设您可以访问C++20,这就是如何使用概念限制模板接受的类型:

template <typename T>
concept printable = requires(T t)
{
    std::cout << t;
};

template <std::ranges::range T>
requires printable<std::ranges::range_value_t<T>>
void print_iter(const T &iterable)
{
    for (const auto &it : iterable)
        std::cout << it << ' ';
    std::cout << '\n';
}
模板
概念可打印=需要(T)
{

std::cout如果您不想使用C++20概念(或锈迹特征),并且仍然希望函数只应用于iterable类型(因为没有人喜欢SFINAE错误),一种技术是要求它具有常量迭代器:

template <typename T>
void print_range(const T& iterable, typename T::const_iterator = T{}.cbegin()) {
    for (const auto& elem : iterable) {
        std::cout << elem << ' ';
    }
    std::cout << std::endl;
}
模板
void print_range(const T&iterable,typename T::const_iterator=T{}.cbegin()){
用于(常量自动和元素:可编辑){

std::cout谢谢,这很有效!是否可以将模板的类型限制为仅支持cout的类型(如在Haskell中,您可以将类型限制为
Show
),或者我应该让它抛出错误?您可以。使用概念或SFINAE。请参阅HolyBlackCat的回答。“或者我应该让它抛出错误”在概念之前,这是最好的(无论如何它只会抛出一个错误!只是…一个更好的错误…)。希望
const auto&
在循环中避免在此处复制。@asterswitwings是的,ty
T
永远无法推断。您可能应该执行
T begin,T end
以允许推断
T
。将其设置为
template
并且您的示例很好您不清楚为什么要继续使用
T
作为容器无论如何,它都不能被推导。在你的代码中,
T
有什么用?(你实际上没有使用它,相反,你可以对迭代器类型进行参数化)除此之外,并非所有迭代器都是某些容器的成员。示例是指针和类似
std::istream\u iterator
的东西。这正是我所寻找的。我没有访问C++20的权限,但当我访问C++20时,这正是我将要做的。我还不太熟悉stackoverflow的礼仪,我应该将这个答案标记为解决方案o吗博洛夫的答案?这更接近我想要的,但博洛夫的答案更适合我的需要。@Peter接受分数是你的,你可以给任何你认为解决了你的问题的人。别担心。只要你接受答案,一切都好。@Peter被接受的答案对未来的读者来说是一个很好的提示,但accepted并不是最好的,所以不管怎样,你必须阅读更多的内容。在C++20中,有多个补充答案也是很常见的,概念是否只允许更好的错误消息?@Eljay更好的错误消息(但不总是),更简单的语法(试着编写这个C++20之前的版本),以及概念相互之间是部分排序的事实,这为函数重载打开了新的可能性。请不要添加“已解决”回答你的问题。接受答案是表明你的问题已经解决的一种方式。@SamVarshavchik真的,已经有涵盖C++20概念的教科书了吗?那将是令人惊讶的。
template <typename T>
void print_range(const T& iterable, typename T::const_iterator = T{}.cbegin()) {
    for (const auto& elem : iterable) {
        std::cout << elem << ' ';
    }
    std::cout << std::endl;
}