如何使用模板化的 constexpr 成员函数初始化 constexpr std::array?

问题描述

这是对我的问题 given here 的跟进。最后,我想创建一个包含带有附加运行索引的文本的 constexpr std::array

我想尝试一种与上一个问题不同的方法。

几乎所有内容,我在下面的代码中所做的都是 constexpr。但也许,这只是返回指向不再存在的变量的指针的老问题。但是,我对此表示怀疑。

请看下面的代码,函数 main 中的 not working 行被标记。

#include <iostream>
#include <algorithm>
#include <iterator>
#include <array>
#include <string>

// Some example text
static constexpr const char BaseString[]{ "text" };

// To create something like "text123" as constexpr
template <const size_t numberToConvert,const char* Text>
class Converter {
public:
    // Some helper variables
    static constexpr size_t TextLength{ std::char_traits<char>::length(Text) };
    static constexpr size_t NumberOfDigits{ ([]() constexpr noexcept {size_t result = 0; int temp = numberToConvert; for (; temp != 0; temp /= 10) ++result; return result; }()) };
    static constexpr size_t ArrayLength{ (numberToConvert ? 1u : 2u) + NumberOfDigits + TextLength };

    // Here we will build the text
    char buf[ArrayLength]{};

    // Constructor: Convert number to character digits
    constexpr Converter() noexcept {
        size_t i{ 0 };  for (; i < TextLength; ++i) buf[i] = Text[i]; // Copy text
        if (numberToConvert == 0) buf[i] = '0';     
        else {
            i = NumberOfDigits + TextLength - 1;    // Convert number to character digits
            int number = numberToConvert; for (; number; number /= 10)
                buf[i--] = number % 10 + '0';
        }
    }
    // cast operator
    constexpr operator const char* () const noexcept { return buf; }
    // For test purposes
    constexpr const char* data() const noexcept { return buf; }
};

// Driver program
int main() {

    // Temporaray constexprs
    constexpr Converter<123,BaseString> conv123{};     // Default construction
    constexpr auto conv2 = Converter<2,BaseString>();  // Assign / copy

    // Build constexpr std::array and initialize it with constexprs
    constexpr std::array< const char*,2> convArray1{ conv123,conv2 };
    // Show that it works
    std::copy(convArray1.begin(),convArray1.end(),std::ostream_iterator<const char*>(std::cout,"\n"));

    // Does compile,but not work. Array will be initialized with nullptr *******************************************
    constexpr std::array< const char*,2> convArray2{ Converter<2,BaseString>(),Converter<2,BaseString>().data() };
    std::cout << convArray2[0] << '\n' << convArray2[0] << '\n';

    return 0;
}

因此,我可以使用模板类创建 constexpr “值”。这些值可以在 constexpr std::array 的“初始化程序”列表中使用。但是,如果我想直接在初始化列表中使用我的类,那么它会编译,但只存储 nullptrs。程序的输出是:

text123
text2
╠╠╠╠╠╠╠╠╠╠╠╠╠╠<½7
╠╠╠╠╠╠╠╠╠╠╠╠╠╠<½7

为什么会这样?或者,有解决方案吗?


使用 Microsoft Visual Studio Community 2019 编译,版本 16.8.2,C++17,调试,X86

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)