C ++ type_traits模板,如果不是const,则添加引用

时间:2015-10-18 14:28:23

标签: c++ templates c++11 typetraits

我有一个接受类型T的类模板。它有一种方法。我希望此方法如果是T则返回const,如果不是T&,则返回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 个答案:

答案 0 :(得分: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>::type为班级类型时返回T,则可以将T const替换为T

下一个问题是result_of,它适用于类型参数;您在问题中的内容是C::method的函数调用。你需要使用

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

但是,既然你需要使用decltype,你可以完全取消result_of

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

最后,当您可以使用static_assert

在编译时进行检查时,在运行时不需要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 :(得分: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;
};