2014-03-31 42 views
0

我有以下代碼:boost :: transform()只有當被添加的值不是NULL時?

// For each trigger model (_1) (which is just a CString), do: 
// m_triggers.push_back(triggers.GetTrigger(static_cast<char const*>(_1))) 
boost::transform(
    model.Triggers(), 
    std::back_inserter(m_triggers), 
    phx::bind(&CTriggerController::GetTrigger, phx::ref(triggers), 
     phx::static_cast_<char const*>(_1))); 

m_triggers是觸發對象的指針的矢量:

std::vector<CTrigger*> m_triggers; 

如果空(這意味着該名稱的觸發可以發現到CTriggerController::GetTrigger()返回呼叫),我不想推動任何東西到我的m_triggers載體。

有沒有一個簡單的方法來做到這一點,通過對我的代碼進行一些小修改?

我使用升壓1.55.0上MSVC9(C++ 03只)

+0

if語句,只需使用一個檢查的價值,如果它不爲空,推到載體。 – OMGtechy

+0

我一直希望有幾次'transform_if',但是在大多數情況下,事實證明,儘早排除邊緣案例會更好。在你的情況下,爲什麼觸發器不在'GetTrigger'中可以接受?看起來這應該是你的系統的不變性,但我可能是錯的。 – pmr

+0

我可以創建自己的'back_inserter_if',但我不確定這是一個優雅的解決方案,因爲我將散佈謂詞邏輯遍佈整個地方。 –

回答

4

您可以使用Boost.Range來同時進行轉換和過濾。

#include <vector> 
#include <iostream> 

#include <boost/range.hpp> 
#include <boost/range/adaptors.hpp> 
#include <boost/range/algorithm.hpp> 

int main() 
{ 
    int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
    std::vector<int> out; 
    using boost::adaptors::filtered; 
    using boost::adaptors::transformed; 
    boost::copy(data | transformed([](int x) { return x + 1; }) 
        | filtered([](int x) { return x % 2 == 0; }), 
       std::back_inserter(out)); 
    for(auto x : out) { 
    std::cout << x << std::endl; 
    } 

    return 0; 
} 

而且東西應該更好地滿足您的使用情況:

boost::copy(
    model.Triggers() | transformed(phx::bind(&CTriggerController::GetTrigger, phx::ref(triggers), 
         phx::static_cast_<char const*>(_1))) 
        | filtered(phx::val(phx::placeholders::_1)), 
    std::back_inserter(m_triggers) 
    ); 
+0

請注意,正如我的問題所示,我正在使用** C++ 03 **。這對我來說不起作用,因爲它大量使用C++ 11功能。 –

+1

@RobertDailey這是示例代碼。只需用Phoenix表達式替換lambda表達式,一切都很好,適配器就可以處理所有的CallableS。 – pmr

+0

我告訴你的是,這是超級誤導。我沒有使用C++ 11的經驗,也不知道如何將你的lambdas翻譯成Phoenix等價物。對於新手來說,有一個明確的例子將是最有幫助和讚賞的。 –

0

首先拷貝到使用std臨時容器:remove_copy_if使用謂詞以除去時GetTrigger() == NULL,然後變換。

相關問題