c++ - 使用 constexpr、SFINAE 和/或 type_traits 对 char*、char 数组和字符串文字进行重载解析

标签 c++ overloading sfinae typetraits enable-if

我遇到了一个有趣的挑战,我已经尝试解决了几个小时,但经过大量研究和多次失败的尝试后,我发现自己在问这个问题。

我想编写 3 个重载函数,每个函数采用以下类型之一:const char*const char(&)[N]字符串文字(例如“BOO”)。我知道字符串文字只是一个字符数组,但在我解释我的方法时请耐心等待。

由于包装器类CharPtrWrapper:

#include <iostream>

class CharPtrWrapper
{
public:
    CharPtrWrapper(const char* charPtr)
        : m_charPtr(charPtr)
    {

    }

    const char * m_charPtr;
};

void processStr(CharPtrWrapper charPtrWrapper)
{
    std::cout << "From function that takes a CharPtrWrapper = " << charPtrWrapper.m_charPtr << '\n';
}

template<std::size_t N>
void processStr(const char (&charArr)[N])
{
    std::cout << "From function that takes a \"const char(&)[N]\" = " << charArr << '\n';
}

int main()
{
    const char* charPtr = "ABC";
    processStr(charPtr);

    const char charArr[] = {'X', 'Y', 'Z', '\0'};
    processStr(charArr);
}

输出:

From function that takes a CharPtrWrapper = ABC
From function that takes a "const char(&)[N]" = XYZ

现在,如果我用字符串文字(例如 processStr("BOO"))调用 processStr,则采用 const char(&) [N] 被调用,这是有道理的,因为字符串文字只是一个字符数组。

这就是我到达问题关键的地方。我无法编写能够区分 char 数组和字符串文字的函数。我认为可能有用的一件事是编写一个采用右值引用的版本:

template<std::size_t N>
void processStr(const char (&&charArr)[N])
{
    std::cout << "From function that takes a \"const char(&&)[N]\" = " << charArr << '\n';
}

但事实证明,字符串文字是左值。我也玩过使用 std::enable_ifstd::is_array 的不同版本,但我仍然没有得到我正在寻找的结果。

所以我想我的问题如下:在现代 C++ 中是否可以区分字符数组和字符串文字?

最佳答案

根据 [expr.prim.id.unqual] :

[...] The type of the expression is the type of the identifier. The result is the entity denoted by the identifier. The expression is an lvalue if the entity is a function, variable, or data member and a prvalue otherwise; it is a bit-field if the identifier designates a bit-field ([dcl.struct.bind]).

因此,给定一个声明

const char arr[] = "foo";

表达式 arrconst char[4] 类型的左值。


根据 [lex.string]/8 :

Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration.

根据[expr.prim.literal] :

A litera is a primary expression. Its type depends on its form. A string literal is an lvalue; all other literals are prvalues.

因此,表达式 "foo"const char[4] 类型的左值。


结论:函数无法区分(const)char 数组和字符串文字。

关于c++ - 使用 constexpr、SFINAE 和/或 type_traits 对 char*、char 数组和字符串文字进行重载解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56468171/

相关文章:

c++ - 编写专门用于类及其子类的函数模板

c++ - 有没有办法编写 "for-eachability"类型的 SFINAE 测试?

c++ - 将 git 命令挂接到 visual studio 预构建步骤

c++ - 使用Qt设计器时如何创建main.cpp?

java - 方法重载和覆盖有什么区别?

c# - 使用接口(interface)和显式实现的函数重载

C++ vector 插入排序算法方法——将 vector 传给方法

c++ - 我的 C++ 应用程序是否依赖于 .Net 框架?

c++ - 基于 bool 模板参数的重载

c++ - void_t 和带有 decltype : are they completely interchangeable? 的尾随返回类型