1

我有一個簡單元函數:如何在Boost.MPL中使用嵌套的元函數?

template <typename T> 
using is_const_lvalue_reference = mpl::and_< 
    std::is_lvalue_reference<T>, 
    std::is_const<typename std::remove_reference<T>::type> 
>; 

顯然,如果T是一個佔位符MPL因爲remove_reference爲佔位符類而不是取代的類型評估它不起作用。如何正確地做到這一點,以便能夠在MPL算法中使用這個元函數?

更新:建議的解決方案是用結構替換別名,這將延遲std::remove_reference中的模板實例化。問題是,如何延遲內聯的實例化,而不是使用任何幫助器結構?

template <typename Sequence> 
using are_const_lvalue_references = mpl::fold< 
    Sequence, 
    mpl::true_, 
    mpl::and_< 
     mpl::_1, 
     mpl::and_< 
      std::is_lvalue_reference<mpl::_2>, 
      std::is_const<typename std::remove_reference<mpl::_2>::type> 
     > 
    > 
>; 

這個例子顯然會因爲同樣的原因而失敗。我應該改變什麼才能使其正確?

回答

2

以這種方式將類型特徵寫爲別名是行不通的,因爲它們會立即被實例化。 is_const_lvalue_reference<_1>正好是mpl::and_<std::is_lvalue_reference<_1>, std::is_const<_1>>(因爲_1不是參考類型) - 因爲左值引用不是const,所以始終爲false。雖然很難寫false_

相反,你必須延遲實例化。只是讓你型特徵從mpl::and_繼承,而不是走樣吧:

template <class T> 
struct is_const_lvalue_reference 
    : mpl::and_< 
     std::is_lvalue_reference<T>, 
     std::is_const<std::remove_reference_t<T>> 
     > 
{ }; 

這樣,std::remove_reference_t<T>不會被實例化,除非我們真正嘗試訪問is_const_lvalue_reference<T>::type - 這不會發生,直到_1被取代了真正的輸入apply


另外,因爲apply<>將調用::type哪裏找到佔位符,你可以只是下降的::type明確調用自己。所以這個工程:

BOOST_MPL_ASSERT((mpl::apply< 
    std::is_const<std::remove_reference<_1>>, 
    int const& 
    >)); 

或與原始表達式:

BOOST_MPL_ASSERT((mpl::apply< 
    mpl::and_< 
     std::is_lvalue_reference<_1>, 
     std::is_const<std::remove_reference<_1>> 
    >, 
    int const& 
    >)); 

注意,這種結構並不作爲一種特質的工作,雖然。

+0

謝謝,它的工作原理是這樣的,但是如果我拋棄struct並只是在原地使用表達式(在一個更大的MPL表達式中),我仍然會遇到同樣的問題。我應該如何處理? – lizarisk

+0

@lizarisk我不知道那是什麼意思。也許問一個具體的新問題? – Barry

+0

我的意思是,我知道將別名轉換爲結構會延遲模板實例化並解決問題,但如果我只想使用內聯表達式(即本例中的'remove_reference'),該怎麼辦?我應該如何延遲模板實例化? – lizarisk