Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C++;编译时 我们今天讨论了“FiZZ嗡嗡”编程测试,我想用C++实现,但是用元编程。理想情况下,它将在编译期间生成输出_C++_Gcc_Fizzbuzz - Fatal编程技术网

在C++;编译时 我们今天讨论了“FiZZ嗡嗡”编程测试,我想用C++实现,但是用元编程。理想情况下,它将在编译期间生成输出

在C++;编译时 我们今天讨论了“FiZZ嗡嗡”编程测试,我想用C++实现,但是用元编程。理想情况下,它将在编译期间生成输出,c++,gcc,fizzbuzz,C++,Gcc,Fizzbuzz,我当前的代码使用模板,但为了生成输出,仍然必须执行模板。在电视上看 我仍然使用std::cout,虽然通过一些模板技巧可以在编译时生成字符串,但在编译时打印它似乎不合理 下面是生成字符串的代码: #include <iostream> #include <type_traits> #include <utility> // Compile time string template <char ...C> struct str_lit {

我当前的代码使用模板,但为了生成输出,仍然必须执行模板。在电视上看


我仍然使用
std::cout,虽然通过一些模板技巧可以在编译时生成字符串,但在编译时打印它似乎不合理

下面是生成字符串的代码:

#include <iostream>
#include <type_traits>
#include <utility>

// Compile time string
template <char ...C> struct str_lit
{
    static constexpr char value[] {C..., '\0'};
};

// Integer to str_lit
constexpr std::size_t cexpr_pow(std::size_t x, std::size_t y)
{
    std::size_t ret = 1;
    while (y--)
        ret *= x;
    return ret;
}
template <std::size_t N, std::size_t X, typename = std::make_index_sequence<X>> struct num_to_sl_impl;
template <std::size_t N, std::size_t X, std::size_t ...Seq> struct num_to_sl_impl<N, X, std::index_sequence<Seq...>>
{
    static constexpr auto func()
    {
        if constexpr (N >= cexpr_pow(10,X))
            return num_to_sl_impl<N, X+1>::func();
        else
            return str_lit<(N / cexpr_pow(10,X-1-Seq) % 10 + '0')...>{};
    }
};
template <std::size_t N> using num_to_sl = decltype(num_to_sl_impl<N,1>::func());

// str_lit concatenation
template <typename F, typename ...P> struct sl_cat_impl {using type = typename sl_cat_impl<F, typename sl_cat_impl<P...>::type>::type;};
template <char ...C1, char ...C2> struct sl_cat_impl<str_lit<C1...>,str_lit<C2...>> {using type = str_lit<C1..., C2...>;};
template <typename F, typename ...P> using sl_cat = typename sl_cat_impl<F, P...>::type;

// The FizzBuzz
template <std::size_t N> struct fizzbuzz_impl
{
    using fizz = std::conditional_t<N % 3 == 0,
                                    str_lit<'f','i','z','z'>,
                                    str_lit<>>;
    using buzz = std::conditional_t<N % 5 == 0,
                                    str_lit<'b','u','z','z'>,
                                    str_lit<>>;
    using type = sl_cat<typename fizzbuzz_impl<N-1>::type,
                        std::conditional_t<N % 3 == 0 || N % 5 == 0,
                                           sl_cat<fizz, buzz>,
                                           num_to_sl<N>>,
                        str_lit<'\n'>>;
};
template <> struct fizzbuzz_impl<0>
{
    using type = str_lit<>;
};
template <std::size_t N> using fizzbuzz = typename fizzbuzz_impl<N>::type;
#包括
#包括
#包括
//编译时字符串
模板结构
{
静态constexpr字符值[]{C..,'\0'};
};
//整数到str_lit
constexpr std::size\u t cexpr\u pow(std::size\u t x,std::size\u t y)
{
标准:尺寸=1;
而(y--)
ret*=x;
返回ret;
}
模板结构num_to_sl_impl;
模板结构num_to_sl_impl
{
静态constexpr auto func()
{
如果constexpr(N>=cexpr_pow(10,X))
将num_返回到_sl_impl::func();
其他的
返回str_lit{};
}
};
使用num_to_sl=decltype(num_to_sl_impl::func())的模板;
//str_-lit级联
模板结构sl_cat_impl{using type=typename sl_cat_impl::type;};
模板结构sl_cat_impl{using type=str_lit;};
使用sl_cat=typename sl_cat_impl::type的模板;
//嘶嘶作响
模板结构fizzbuzz_impl
{
使用fizz=std::conditional\u t;
使用buzz=std::conditional\u t;
使用类型=sl_cat;
};
模板结构fizzbuzz_impl
{
使用类型=str_lit;
};
使用fizzbuzz=typename fizzbuzz_impl::type的模板;
用法示例:

int main()
{
    std::cout << fizzbuzz<15>::value;
}
intmain()
{

std::难道您不能在编译时以平台无关的方式打印(但),但是,您可能感兴趣的是,编译时计算的要点不是在编译时输出结果。它是在编译时生成结果,以便使用(例如:输出)在运行时它将使用常量。但是,我想,如果你真的想,你可能会编写一些复杂的模板魔术,在编译时将结果作为编译器错误消息的一部分打印出来——虽然这很愚蠢。好吧,如果你能构建一个字符串,你可以在代码的末尾触发一个
静态断言
它将字符串显示为错误。一致性编译器不需要为格式良好的程序发出任何诊断信息,因此无法使用格式良好的程序回答您的问题。您最好创建一条包含结果的错误消息(例如,作为错误构造的模板参数或数组大小,或者作为静态断言)。当然,对格式错误的程序的任何诊断也是未指定的,因此编译器可能只会说“boo”。
int main()
{
    std::cout << fizzbuzz<15>::value;
}