【问题标题】:Template function with iterators but fixed type具有迭代器但类型固定的模板函数
【发布时间】:2012-12-26 04:05:33
【问题描述】:
ProcessIndex( int index );

template< typename Iterator >
void ProcessIndexes( Iterator start, Iterator end )
{
    while( start!=end )
    {
        ProcessIndex(*start++);
    }
}

我怎样才能强制这个函数只能用一个特定的、固定的迭代器值类型来调用,例如int(但任何容器类型)?在这种情况下,ProcessIndex()int 作为输入,因此,非原始类型的编译失败并生成警告,例如float。但是,我希望声明强制执行 int,这样除了 int 之外的所有编译都失败。

尽管努力了,但在这里或其他地方还没有找到“解决方案”,这是否微不足道(?)。

【问题讨论】:

  • static_assert(std::is_same&lt;typename std::iterator_traits&lt;Iterator&gt;::value_type, int&gt;::value, "ProcessIndexes: Iterators must point to int."); -- 不知道你为什么想要那个,但是嘿......
  • 你确定模板函数和迭代器在这种情况下是合适的吗?为什么不传递int 的向量或int 的数组?
  • Xeo 有正确的方法,但我会跳过iterator_traits,只测试decltype(*start)
  • Re ahenderson:因为函数(实际上是一个类方法)也应该接受 std::list、std::set、std::map、std::you_name_it :-) 我会喜欢的传递具有固定类型的任意容器,但了解到它通常使用迭代器完成,这具有排除 c 样式类型数组的额外好处。
  • @Ben:我不会,因为decltype(*start) 可能是int&amp;int const&amp;。 :)

标签: c++ templates stl function-templates


【解决方案1】:

使用 C++11,您可以使用 enable_ifis_samedecay 执行此操作,如下所示:

#include<iostream>
#include <type_traits>
#include <vector>

void ProcessIndex( int index )
{
    //do something here
    std::cout<<"Inside ProcessIndex with: "<< index <<std::endl;
}

template< typename Iterator >
auto ProcessIndexes( Iterator start, Iterator end ) -> typename std::enable_if<std::is_same<typename std::decay<decltype(*start)>::type, int>::value>::type
{
    std::cout<<"Inside ProcessIndexes"<<std::endl;
    while( start!=end )
    {
        ProcessIndex(*start++);
    }
}

int main(){
    std::vector<int> vec{1,2,3};
    ProcessIndexes(vec.begin(), vec.end()); //WORKS

    std::vector<float> vec2;
    //ProcessIndexes(vec2.begin(), vec2.end()); //this won't work
}

【讨论】:

    【解决方案2】:

    从 C++20 开始,您可以使用新概念和 requires 关键字来检查迭代器是否指向 int 类型:

    #include <vector>
    
    void ProcessIndex( int ) {}
    
    template< typename Iterator >
    void ProcessIndecies( Iterator start, Iterator end )
        requires( std::same_as<std::decay_t<decltype(*start)>, int> )
    {
        while( start!=end )
        {
            ProcessIndex(*start++);
        }
    }
    
    int main() {
        std::vector<int> vi;
        ProcessIndecies(vi.begin(), vi.end()); //ok
    
        std::vector<float> vf;
        //ProcessIndecies(vf.begin(), vf.end()); //fails
    }
    

    演示:https://gcc.godbolt.org/z/hba1qh8bz

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-12
      • 1970-01-01
      • 2012-01-20
      • 1970-01-01
      • 2016-05-24
      • 1970-01-01
      相关资源
      最近更新 更多