2017-08-24 121 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

相关问题