2017-08-24 122 views
0

爲了優化我的代碼,在我看來,如果我可以將指針指向一個成員函數str1str2作爲參數fill_vec而不是在fill_vec中有兩個顯式循環。傳遞指向成員函數的指針作爲C++的參數11

在C++ 11中有這樣做的首選方法嗎?或者你建議採取不同的策略?


#include <iostream> 
#include <vector> 
#include <map> 

class Base 
{ 
    private: 
    std::map<int, std::string> m_base1, m_base2; 
    std::vector<std::string> m_str1 = {"one", "two", "three"}; 
    std::vector<std::string> m_str2 = {"four", "five", "six"}; 

    public: 
    std::vector<std::string> &str1() { return m_str1; } 
    std::vector<std::string> &str2() { return m_str2; } 

    std::map<int, std::string> &base1() { return m_base1; } 
    std::map<int, std::string> &base2() { return m_base2; } 
}; 

template <typename T> 
void fill_vec(T *b) 
{ 
    size_t counter = 0; 
    for (const auto &str_iter : b->str1()) 
     (b->base1())[counter++] = str_iter; 

    counter=0; 
    for (const auto &str_iter : b->str2()) 
     (b->base2())[counter++] = str_iter; 
} 

int main(int argc, char *argv[]) 
{ 
    Base *b = new Base; 
    fill_vec(b); 

    return 0; 
} 
+0

難道你需要一個指針傳遞給'base1' /'BASE2 '以及? –

+0

@ChrisDrew不在我目前的設計。 – N08

+1

爲什麼不使用一個循環,因爲矢量大小相同? – Griffin

回答

0

推薦做法將決定了fill_vec()應該是基地的一員,最好從構造函數調用,所以對象將準備創建後使用。

但是,由於映射m_base1和m_base2是常量,因此應該取消m_str1和m_str2,使m_base1和m_base2靜態並直接在構造函數中初始化它們。

而且,您應該儘可能使用智能指針。

這給:

#include <iostream> 
#include <vector> 
#include <map> 
#include <string> 
#include <memory> 

class Base 
{ 
    private: 
    static std::map<int, std::string> m_base1, m_base2; 

    public: 
    Base(); // WARNING !! must create a object before using maps! 

    static const auto & base1() { return m_base1; } 
    static const auto & base2() { return m_base2; } 
}; 


// in base.cpp 

std::map<int, std::string> Base::m_base1; 

Base::Base() 
{ 
    if (m_base1.empty()) 
    { 
     m_base1[0] = "one"; 
     m_base1[1] = "two"; 
     m_base1[2] = "three"; 
    } 
    if (m_base2.empty()) 
    { 
     m_base2[0] = "four"; // doesn't look right, but equivalent to original code 
     m_base2[1] = "five"; 
     m_base2[2] = "six"; 
    } 
} 


// in your main module.. 

int main(int argc, char *argv[]) 
{ 
    // auto b = std::unique_ptr<Base>(new Base{}); 
    // this would be best since Base is very small. 
    Base b; 

    // this prints the string "two six" 
    std::cout << b.base1().at(1) << " " << b.base2().at(2) << '\n'; 

    return 0; 
} 
+1

他的'map'是基於0的,不是嗎? 'm_base1 [0] =「one」;' – pingul

+0

不,地圖基於_not_ 0,std :: map 將任意整數值映射到字符串。 –

+0

當然可以,但是用'counter = 0'做'm_base1 [counter ++]'將評估爲0.另外,請注意,您更改了'm_base1,m_base2'的簽名:他沒有靜態。 – pingul

0

這是可能的,但我想,基於上述評論檢查它的實用性。

像這樣的東西會工作:

template <typename T> 
void fill_vec(Base* obj, std::map<int, std::string>& (T::*mapv)(), std::vector<std::string>& (T::*vec)()) 
{ 
    size_t counter = 0; 
    for (const auto &str_iter : (obj->*vec)()) 
     (obj->*mapv)()[counter++] = str_iter;  
} 

int main(int argc, char *argv[]) 
{ 
    Base *b = new Base; 
    fill_vec(b, &Base::base1, &Base::str1); 

    return 0; 
} 

這是工作以類似的方式如何,你通常會通過pointer to member fields

相關問題