【发布时间】: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 <size_t ... N> constexpr auto concat(ct_string<N>...)之类的参数,因为即使使用ct_string的推导指南也无法推导N。
【问题讨论】:
-
print_type打印一个指针,因为当您将一个数组“按值”传递给print_type时,它会立即衰减为一个指针,所有关于它是一个数组的信息都将丢失。print_type(const T &t)解决了这个问题,并导致你的第二个关于歧义的问题。我的最佳答案是“因为标准是这么说的”。 -
像
"oceanic"这样的文字字符串实际上是常量字符数组。因此,它们可以通过对数组重载的引用或指针重载来使用,这使得它变得模棱两可。 -
@Someprogrammerdude 他们是
const char[8](长度为 8),不是吗?同样的歧义发生在const int[8] -
void print_type(T t)——这里的T已经是const char *。这艘船已经起航了。 -
数组不是按值传递的。
std::is_array<typename std::remove_reference<T>::type>::value也可能有用。
标签: c++ arrays c++17 overload-resolution