2012-01-10 54 views
0

我嘗試實現static_cast的函子版本,以便在std::bind()中使用。函數版本的std :: bind()中的static_cast()

我知道Boost ll_static_cast<K>()(請參閱using static_cast with boost::bind),但我現在沒有使用Boost。

有在Why do several of the standard operators not have standard functors?一個代碼示例,但它不會在GCC 4.2.1編譯:

template <typename Target> 
struct StaticCast 
{ 
    template <typename Source> 
    Target operator()(Source&& source) const 
    { 
     return static_cast<Target>(source); 
    } 
} 

我設法得到的東西來編譯,但我不知道這是正確的:

template <class Target> 
struct StaticCast : public std::unary_function<void, Target> { 
    template <class Source> 
    Target operator()(Source& src) const { 
     return static_cast<Target>(src); 
    } 
}; 

有人可以告訴我,如果這個版本是正確的,並且如果是這種情況,爲什麼我需要std::unary_function這是不是在前面的代碼示例中使用?

用法:

std::vector<BaseObject*> vec; // BaseObject* are known to be of type 
    // DerivedObject* of course, please don't ask me how or why... 

std::for_each(vec.begin(), vec.end(), 
    std::bind(&DerivedObject::doStuff, 
     std::bind(StaticCast<DerivedObject*>(), std::placeholders::_1), 
    "with some string")); 
+0

如果您使用C++ 11,但不使用lambda表達式? 'std :: for_each(vec.begin(),vec.end(),[](BaseObject * obj){static_cast (obj) - > doStuff();}' – kennytm 2012-01-10 16:15:19

+0

不幸的是,我被GCC 4.2.1暫時不支持它們(爲簡單起見,我在代碼中刪除了'tr1 ::') – OlivierB 2012-01-10 16:17:44

回答

0

由於缺乏在C++ 03的完美轉發,你就必須做出應有與重載:

template<class Target> 
struct StaticCast 
{ 
    typedef Target result_type; 

    template<class Source> 
    Target operator()(Source& src) const 
    { 
     return static_cast<Target>(src); 
    } 

    template<class Source> 
    Target operator()(Source const& src) const 
    { 
     return static_cast<Target>(src); 
    } 
}; 

注我明確地做出typedefresult_type而不是繼承std::unary_function<>。原因是std::unary_function<>的第一個模板參數應該是operator()的參數類型,但由於我們的operator()是一個模板,所以我們無法預先知道這一點,所以首先提供一個模板是不合理的(特別是void,這意味着operator()是空的,實際上它是一元的)。


此外,爲了完整性,這裏是正確的C++ 11版本的函子:

template<class Target> 
struct StaticCast 
{ 
    template<class Source> 
    Target operator()(Source&& source) const 
    { 
     return static_cast<Target>(std::forward<Source>(source)); 
    } 
} 
0

一個原因第一個不能正常工作,可能是因爲您使用的是不支持C++ 11編譯器右值引用。

您需要std::unary_function的原因是爲您的課程啓用std::result_of,因爲在C++ 98中沒有decltype,所以std::bind用於推導結果類型。

如果你看看std::unary_function,你會看到,它從模板參數傳遞,這是在用轉身直接std::result_ofstd::bind定義類型result_type

+0

事實上,即使沒有右值引用它也不起作用,所以我猜想原因是推導出瞭如果我理解正確,類型可以在C++ 11中自動推導而不是在C++ 98中? – OlivierB 2012-01-10 16:31:46

+0

@OlivierB:這就是爲什麼我寫了**一個**原因。是的,類型不能在C中自動推導出來++ 98,而它可以在C++ 11中使用'decltype'。 – ronag 2012-01-10 16:32:43

0

好了,一般你的代碼是壞:

首先,你可能有臨時對象和r值同時要求他們

例如

float f = StaticCast<float>()(4); 

非const引用的煩惱甚至不會編譯。

然後,你複製的對象,而鑄造。這可能不是你想要的。

源舉例說免費缺點由於move語義

+0

嗯,我不得不同意......據我所知,GCC 4.2.1並沒有完美的方式。 – OlivierB 2012-01-10 16:49:09

相關問題