c++ 是否可以将模板测试解析为数组引用而不是指向数组指针?

hwamh0ep  于 2023-01-03  发布在  其他
关注(0)|答案(1)|浏览(120)

免责声明:这是一个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 *是否为字符串。
  • 对于template <size_t ... N> constexpr auto concat(ct_string<N>...)这样的参数,不能使用ct_string的变元列表,因为即使使用ct_string的推导指南,也不可能推导出N
62lalag4

62lalag41#

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 {
        // ...
    }
}

相关问题