【问题标题】:Compiletime narrowing wchar to char编译时将 wchar 缩小为 char
【发布时间】:2020-02-21 12:08:46
【问题描述】:

在我的编译时函数中,我想使用字符串。 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);
}

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

【问题讨论】:

  • 为什么不把wchar_t字符串当作一个字节数组,然后计算校验和呢?
  • 这正是我想做的,但这迟早需要缩小范围。我的意思是一旦你必须根据我的知识将 wchar* 转换为 char*。
  • 不需要缩小范围,除非您想将wchar_t 字符 转换为char。只需转换为const char*,您就有一个指向字节缓冲区的指针。
  • 我可能错了,但在我的示例代码中,我正试图这样做并且无法编译。请检查一下好吗?

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


【解决方案1】:

您的代码中的基本问题是您不能使用 static_cast 在指向不同数据类型的指针之间进行转换 - 当这些类型不相关时,char 和 wchar_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 函数就不能再在编译时被评估,所以你的main 中的两个constexpr 声明将失败,你将不得不只使用@ 987654330@改为:

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

编辑: 另一种方法(也许更好)是使用 function-style 强制转换:

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

有了这个,您可以将constexpr 用于encrypted,但不能用于wencrypted!

【讨论】:

  • 我想在编译时这样做,所以简单地删除 constexpr 对我来说不是一个选择。
猜你喜欢
  • 2011-02-28
  • 1970-01-01
  • 2011-06-17
  • 2019-12-05
  • 2012-09-25
  • 2012-04-03
  • 1970-01-01
  • 2013-03-30
  • 1970-01-01
相关资源
最近更新 更多