【问题标题】:is it possible to resolve template T to array reference instead of pointer to an array?是否可以将模板 T 解析为数组引用而不是指向数组的指针?
【发布时间】:2023-01-01 03:16:08
【问题描述】:

免责声明:这是一个XY问题亲切的问题。

是否可以将template <typename T> 解析为(const T (&)[N]) 重载而不是(const T*)
例如:

template <typename T>
void _print_type(T)
{
    std::cout << "not a c array\n";
}

template <typename T, size_t N>
void _print_type(const T (&)[N])
{
    std::cout << "ref c array\n";
}

template <typename T>
void _print_type(const T *)
{
    std::cout << "pointer to c array\n";
}

template <typename T>
void print_type(T t)
{
    _print_type(t);
}

int main(){
  print_type("oceanic"); // prints "pointer to c array\n"
}

为什么 _print_type("oceanic"); 会导致调用不明确?当有数组时,更喜欢引用数组的重载不是合乎逻辑的吗?


XY 问题(不是问题的一部分):
采用不同字符串类型的连接函数

const ct_string staticString = "I am static";
concat("string literal", staticString, "another literal"); // yields contigeous ct_string
concat("string literal", staticString, std::string("dynamic string")); // yields std::string
  • 可以在编译时算出 const char* 的长度。一不能强制检查 const char * 是否为字符串文字。
  • 不能将 ct_string 的可变参数列表用于 template &lt;size_t ... N&gt; constexpr auto concat(ct_string&lt;N&gt;...) 之类的参数,因为即使使用 ct_string 的推导指南也无法推导 N

【问题讨论】:

  • print_type 打印一个指针,因为当您将一个数组“按值”传递给 print_type 时,它会立即衰减为一个指针,所有关于它是一个数组的信息都将丢失。 print_type(const T &amp;t) 解决了这个问题,并导致你的第二个关于歧义的问题。我的最佳答案是“因为标准是这么说的”。
  • "oceanic" 这样的文字字符串实际上是常量字符数组。因此,它们可以通过对数组重载的引用或指针重载来使用,这使得它变得模棱两可。
  • @Someprogrammerdude 他们是const char[8](长度为 8),不是吗?同样的歧义发生在const int[8]
  • void print_type(T t)——这里的T已经是const char *。这艘船已经起航了。
  • 数组不是按值传递的。 std::is_array&lt;typename std::remove_reference&lt;T&gt;::type&gt;::value 也可能有用。

标签: c++ arrays c++17 overload-resolution


【解决方案1】:

CWG 最近决定,将数组引用绑定到数组参数应被视为比将数组衰减为指针更好的隐式转换。 CWG 1789

在更新标准的措辞并且编译器开始实施新行为之前,您必须通过转发引用来获取参数来解决歧义:

template <typename T>
void print_type(T&& t) {
    if constexpr(std::is_pointer_v<std::remove_reference_t<T>>) {
        // call pointer implementation
    } else if constexpr(std::is_array_v<std::remove_reference_t<T>>) {
        // call array implementation
    } else {
        // ...
    }
}

【讨论】:

    猜你喜欢
    • 2014-05-15
    • 2021-07-18
    • 1970-01-01
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    相关资源
    最近更新 更多