首页 > 解决方案 > 编译时将 wchar 缩小为 char

问题描述

在我的编译时函数中,我想使用字符串。ANSI 和 WIDE 的。所以,我添加了一个快速模板来处理这两个问题。这一切都很容易,但我有一个特殊的函数可以计算字符串的安全校验和。这适用于字节数组,重写以处理可变缓冲区大小需要相当大的努力,所以我想我只需将 wchar 缩小到 char 并让我的函数在它上面工作。默认情况下,它不像我认为的那样工作。

重现我的问题的示例代码: https ://godbolt.org/z/ya2zq7

#include <iostream>

constexpr void hack(const char* const from, const size_t fromLen, char* const to)
{
    for (size_t i = 0; i < fromLen; i++)
    {
        to[i] = from[i] + 1;
    }
}

template <typename U, std::size_t LENGTH>
class EncryptedStorage
{
    U m_data[LENGTH]{};

public:
    constexpr EncryptedStorage(const U* input)
    {
        hack(static_cast<const char* const>(input), LENGTH * sizeof(U), static_cast<char* const>(m_data));
    }
};

int main()
{
    // Test with CHAR
    constexpr char test[] = "Hello World";
    constexpr size_t size = sizeof(test) / sizeof(test[0]);
    constexpr auto encrypted = EncryptedStorage<char, size>(test);

    // test with WCHAR
    constexpr wchar_t wtest[] = L"Hello World";
    constexpr size_t wsize = sizeof(wtest) / sizeof(wtest[0]);
    constexpr auto wencrypted = EncryptedStorage<wchar_t, wsize>(wtest);
}

如果您注释宽字符串,它将完美编译。是否有可能做我想做的事,或者我真的应该重新设计我的所有算法以处理可变大小?

标签: c++visual-c++c++17compile-time

解决方案


代码中的基本问题是,您不能使用static_cast在指向不同数据类型的指针之间进行转换——当这些类型是不相关charwchar_t;为此,您需要一个reinterpret_cast或一个C风格的演员表:

constexpr EncryptedStorage(const U* input)
{
    hack(reinterpret_cast<const char* const>(input), LENGTH * sizeof(U), reinterpret_cast<char* const>(m_data));
}

但是,一旦您进行了这样的转换,您的EncyptedStorage函数就无法在编译时进行评估,因此您的两个constexpr声明main将失败,您将不得不使用const

const auto encrypted = EncryptedStorage<char, size>(test);
const auto wencrypted = EncryptedStorage<wchar_t, wsize>(wtest); // Can't use constexpr

编辑:另一种方法(也许更好)是使用函数式强制转换:

using pcchar = const char* const;
using pchar = char* const;
constexpr EncryptedStorage(const U* input)
{
    hack(pcchar(input), LENGTH * sizeof(U), pchar(m_data));
}

有了这个,你可以使用constexprforencrypted但不能 for wencrypted


推荐阅读