我想为这样的调用获取三个不同的函数:
foo("aa");
像这个:
char buf[2];
foo(buf);
还有一个像这样的调用的变体:
const char *ptr;
//set ptr
foo(ptr);//don't know buffer size at compile time
我试试这个:
//and foo1 for pointers, but how???
template<size_t N>
void foo1(char (&)[N], std::false_type)
{
std::printf("not const\n");
}
template<size_t N>
void foo1(const char (&)[N], std::true_type)
{
std::printf("const\n");
}
template<typename arr_t>
void foo(arr_t arr)
{
foo1(std::forward<arr_t>(arr), std::is_const<typename std::remove_reference<arr_t>::type>{});
}
foo("a");
但它编译失败,看起来像“a”转换为
const char *
不是const char (&)[2]
,
但有趣的是,这样的代码编译得很好:
template<size_t N>
void f(const char (&)[N])
{
}
f("aaaa");
那么我如何在编译时常量(并在编译时知道该常量的大小)和已知大小但不是常量的数组之间重载函数?
最佳答案
这里有两个问题。首先,您的调度函数正在按值获取其参数。要做到完美转发,您应该通过转发引用来表达您的论点。
第二个让我吃惊的问题是pointer decay takes priority over a deduced template因此,与采用数组的模板相比,采用指针的函数将优先被调用。
您可以使用 std::is_array
类型特征标记分派(dispatch)。
template<size_t N>
void foo1(char (&)[N], std::true_type)
{
std::cout << "array\n";
}
template<size_t N>
void foo1(const char (&)[N], std::true_type)
{
std::printf("const array\n");
}
void foo1(const char*, std::false_type)
{
std::cout << "pointer\n";
}
template<typename T>
void foo(T&& x)
{
foo1(std::forward<T>(x), std::is_array< typename std::remove_reference<T>::type >());
}
关于C++重载静态常量字符串与字符数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32513517/