告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '' 结尾

Tell a const char array that does not ends with '' apart from a C-style string in compile time

本文关键字:样式 字符串 结尾 一个 const 编译 数组 char      更新时间:2023-10-16

是否可以在编译时将不以''结尾的const char数组与C样式字符串区分开来?

假设我想为一个类编写两个构造函数。

一个构造函数从C样式字符串构造,该字符串以''结尾。

另一个具有不同行为的构造函数从不以''结尾的const char数组中进行构造。

作为一个最小的例子,考虑

#include <cstddef>
#include <iostream>
struct Foo
{
Foo(const char *)
{
std::cout << "a C-style string" << std::endl;
}
// Question: How to modify Foo so that a const char array that does not
//           ends with '' will go to a different constructor?
template<size_t N>
Foo(const char (&)[N])
{
std::cout << "a const char array "
"that does not ends with '\0'" << std::endl;
}
};
int main()
{
Foo("a C-style string");          // print "a C-style string"
const char a[3] {'a', 'b', 'c'};
Foo foo(a);                       // print "a C-style string" - can it change?
return 0;
}

g++ -std=c++17编译。

问题:有什么方法可以做到这一点吗?

也许我可以应用SFINAE技术,但我还没有想好如何做到这一点。

注意:目前在StackOverflow上有几个类似但不完全相同的问题。我没有找到一个能直接回答我问题的

不,那样是不可能的。在重载解析时,非模板函数更可取。C++模板函数过载分辨率

非模板函数是一流的公民。

为什么具有"相同签名"的模板和非模板函数的重载会调用非模板函数?

当模板函数和非模板函数都可用于解析函数调用时,将选择非模板函数。

可能的解决方法:

struct Foo
{
void Cstr(const char *)
{
std::cout << "a C-style string" << std::endl;
}
template<size_t N>
Foo(const char (&s)[N])
{
if (N > 0 && !s[N - 1])
Cstr(s);
else
std::cout << "a const char array "
"that does not ends with '\0'" << std::endl;
}
};

一件有趣的事情是,如果在数组声明中删除const,它将与数组构造函数一起使用

#include <cstddef>
#include <iostream>
struct Foo
{
Foo(const char *)
{
std::cout << "a C-style string" << std::endl;
}
template<size_t N>
Foo(const char (&)[N])
{
std::cout << "a const char array "
"that does not ends with ''" << std::endl;
}
};
int main()
{
Foo("a C-style string");
// const char a[3] {'a', 'b', 'c'};
char a[3] {'a', 'b', 'c'};
Foo foo(a);
return 0;
}