如何避免使用模板参数扣除衰减



简化:

// CHAR_TYPE == char, wchar_t, ...
template <typename CHAR_TYPE, unsigned CHAR_COUNT>
void Foo(CHAR_TYPE const (&value)[CHAR_COUNT]) noexcept
{
    TRACE("const ref array");
    // perform a bit of logic and forward...
}
template <typename CHAR_TYPE>
void Foo(CHAR_TYPE const* value) noexcept
{
    TRACE("const ptr");
    // perform a bit of logic and forward...
}
// [ several other overloads ]

呼叫:

char const* ptr = ...
wchar_t const* wptr = ...
Foo(ptr);     // <-- good: "const ptr"
Foo(wptr);    // <-- good: "const ptr"
constexpr char const buffer[] { "blah blah blah" };
constexpr wchar_t const wbuffer[] { L"blah blah blah" };
Foo(buffer);  // <-- ambiguous
Foo(wbuffer); // <-- ambiguous

当然,我可以删除const Ref数组过载。但是,我想以不同的方式处理这些类型。我试图有条件地实现正确的过载,但是我无法确定必要的条件。

template <typename CHAR_TYPE, unsigned COUNT>
typename std::enable_if</* std::is_?? */, void>::type
    Foo(CHAR_TYPE const (&value)[COUNT]) noexcept
{
    TRACE("by ref array");
    // perform a bit of logic and forward...
}
template <typename CHAR_TYPE>
typename std::enable_if</* std::is_?? */, void>::type
    Foo(CHAR_TYPE const* value) noexcept
{
    TRACE("ptr");
    // perform a bit of logic and forward...
}

消除这些超载的最佳方法是什么?
(我希望不使用阵列包装器)

有效的一个想法是删除指针,而简单地将Tstd::enable_if_t<std::is_pointer<T>::value>卫队一起使用。简化的示例下面:

#include <iostream>
#include <type_traits>
template<class T, size_t N>
void f(T const (&) [N])
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}
template<class T, std::enable_if_t<std::is_pointer<T>::value>* = nullptr >
void f(T)
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}
int main()
{
    const char* str = "test";
    char str2[]{"test2"};
    f(str);
    f(str2);
}

活在Coliru

通过(const)参考块在模板参数扣除期间阵列段衰减(const)引用块。请参阅[temp.deduct.call]/2。所以:

template <typename CHAR_TYPE>
void Foo(CHAR_TYPE const* const & value) noexcept
{
    TRACE("const ptr");
    // perform a bit of logic and forward...
}

最新更新