2015-10-18 61 views
3

我有一個類模板,接受類型T。它有一個方法。如果它是constT&,如果它不是const,我希望此方法返回類型TC++ type_traits模板添加引用,如果不是const

template<typename T> 
class C 
{ 
    static typename add_reference_if_non_const<T>::type method(); 
}; 

int main() 
{ 
    assert(is_same<result_of<C<int>::method()>::type, int&>::value); 
    assert(is_same<result_of<C<const int>::method()>::type, const int>::value); 
} 

我該怎麼辦?

回答

2

你想要的C<int const>::method()返回類型爲int const,但top-level cv qualifiers are ignored on function return types。無論如何,由於method()返回T的副本,你真的很在乎你是否返回T const而不是T

鑑於這種情況,我想你想要的是以下

using add_reference_if_non_const = 
    typename std::conditional<std::is_const<T>{}, 
           typename std::remove_const<T>::type, 
           typename std::add_lvalue_reference<T>::type 
       >::type; 
static add_reference_if_non_const method(); 

您可以替換typename std::remove_const<T>::typeT,如果你想返回T constT是一個類類型。


下一個問題是result_of與類型參數一起使用;你在這個問題上有一個C::method函數調用。您需要使用

result_of<decltype(&C<int>::method)()>::type 

但既然你需要使用decltype無論如何,你可以完全result_of做了。

decltype(C<int>::method()) 

最後,你不必assert在運行時,你可以用make在編譯時檢查static_assert

static_assert(is_same<decltype(C<int>::method()),  int&>::value, ""); 
static_assert(is_same<decltype(C<int const>::method()), int>::value, ""); 

Live demo

1

如何:

template <typename T> 
struct add_reference_if_non_const 
{ 
    using type = std::conditional<std::is_const<T>::value, T, std::add_lvalue_reference<T>>::type; 
};