2017-04-10 104 views
3

最近我一直在學習動態內存分配。使用迭代器參數從模板函數返回指針

爲了實踐的目的,我嘗試了一個通用函數,它可以接受迭代器作爲參數,然後從頭到尾複製到動態分配的數組,然後返回一個指針。

我想使用完整的演繹功能,例如調用函數時不指定返回類型。如果可能的話,我還希望函數聲明儘可能地簡單,沒有任何庫(如果需要,除std::remove_reference以外,如果需要的話,type_traits)。

以下代碼不會編譯。而且我知道從邏輯角度來看代碼是無用的。我只是想告訴你我的意圖,我想實現...

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

template<typename T> 
auto* returnPointer(T iter1, T iter2) -> std::remove_reference<decltype(*iter1)>::type 
{ 
    auto p = new std::remove_reference<decltype(*iter1)>::type [10]; 
    auto p_help = p; 

    while(iter1 != iter2) 
    { 
     *p_help = *iter1; 
     p_help++; 
     iter1++; 
    } 

    return p; 
} 

int main() 
{ 
    std::vector<int> v {0,1,2,3,4,5,6,7,8,9}; 
    int *p = returnPointer(v.begin(), v.end()); 

    for(int i = 0; i < 10; i++) 
     std::cout << p[i] << " "; 

    return 0; 
} 

我明白爲什麼它不會編譯,我無法弄清楚如何使它工作我想象的方式......

任何幫助非常感謝! :)

回答

3
  1. 當使用尾隨返回類型聲明時,應該直接使用auto;
  2. 您需要爲std::remove_reference<...>::type添加typename,或者使用std::remove_reference_t(因爲C++ 14)。

然後

auto returnPointer(T iter1, T iter2) -> typename std::remove_reference<decltype(*iter1)>::type* 
// ~         ~~~~~~~~            ~ 

LIVE


其他建議:

  1. 由於C++ 14你可以利用返回類型推演的。所以只是

    template<typename T> 
    auto returnPointer(T iter1, T iter2) 
    { 
        auto p = new std::remove_reference_t<decltype(*iter1)> [10]; 
        ... 
        return p; // return type will be deduced from p 
    } 
    
  2. 您可以使用std::distance來獲取元素的個數,如

    auto p = new std::remove_reference_t<decltype(*iter1)> [std::distance(iter1, iter2)]; 
    
  3. 不要忘記delete[]最後指針,即

    delete[] p; 
    

LIVE

+0

我很近!驚人!我在另一個地方忘記了'typename',這是我分配數組的地方。我剛剛測試過,它的工作原理!謝謝!你能解釋一下''''''''之後的祕密是什麼? – galaxyworks

+1

@galaxyworks很簡單,'std :: remove_reference <...> :: type'將返回元素的類型,添加'*'使它成爲指向元素的指針的類型。對於你的代碼和'std :: vector '一起工作,'std :: remove_reference <...> :: type'將會是'int',並且加上'*'使它成爲'int *'。 – songyuanyao

+0

我現在明白了!感謝您的回答和詳細的解釋! – galaxyworks