采用数组参数的模板函数与采用指针参数的重载函数

Kis*_*dda 8 c++

考虑下面的代码

#include <iostream>
#include <cstring>

template <int size>
void func(const char (&arr)[size])
{
    //Prefer this function for const string literals.
    std::cout << "Array of " << size - 1 << " bytes" << std::endl;
}

void func(const char *arr)
{
    //Use this for all other strings that are not literals
    std::cout << "String of " << strlen(arr) << " bytes" <<std::endl;
}

int main()
{
    func("Hello!");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如何确保示例中调用的是模板函数而不是重载?

我希望模板化函数在字符串文字上调用,而另一个可用于所有其他情况。使用模板化函数,我可以避免调用 strlen()。在我的应用程序中,这两个函数最终都创建了一个 string_view 对象。

我想知道如何选择过载。

dfr*_*fri 4

问题在于,在重载解析期间对标准转换序列进行排名时,数组到指针的转换将计为精确匹配排名。由于数组重载是一个模板,因此指针重载变得更好匹配。

您可以为指针重载添加一个代理对象,以强制它进入比参数类型为 时的数组重载更糟糕的转换序列const char (&)[N]

namespace detail {
struct Proxy {
  Proxy(const char *ptr) : ptr_{ptr} {};
  operator const char *() const { return ptr_; }

private:
  const char *ptr_;
};
} // namespace detail

template <int size> void func(const char (&arr)[size]) {
  // Prefer this function for const string literals.
  std::cout << "Array of " << size - 1 << " bytes" << std::endl;
}

void func(detail::Proxy const &proxy) {
  // Use this for all other strings that are not literals
  std::cout << "String of " << strlen(proxy) << " bytes" << std::endl;
}

int main() {
  func("Hello!"); // Array of 6 bytes
  const char *str = "Hello!";
  func(str); // String of 6 bytes
}
Run Code Online (Sandbox Code Playgroud)