gcc c ++ 11限制用户定义的常量和模板参数包

Вов*_*ова 13 c++ c++11 gcc4.7

我一直在gcc 4.7.2中玩用户定义的常量,并遇到了一些我不太了解的大小限制因素.

我们的想法是为定点十进制类型定义一个constexpr运算符"".我想避免使用variadic模板从double进行转换,而是在编译时解析尾数和指数.尾数解析证明有点棘手.

当我启用下面代码底部的3条禁用行中的任何一行时,gcc会陷入无限循环并挂起.我注意到浮点文字的最大大小和可变参数模板的显式实例化,但整数文字的大小略大.

我用了命令:g ++ -std = c ++ 11 -Wall -g -o literal_value literal_value.cpp

使用-ftemplate-depth-128没有区别.

#include <iostream>
#include <cstdint>

typedef std::uint64_t value_type;

template<value_type Temp, char... List> struct literal_parser;

template<value_type Temp, char Head, char... List>
struct literal_parser<Temp, Head, List...>
{
    static const value_type value = Head == '.' ?
        literal_parser<Temp, List...>::value :
        literal_parser<Temp * 10 + Head - '0', List...>::value;
};

template<value_type Temp, char Last>
struct literal_parser<Temp, Last>
{
    static const value_type value = Last == '.' ?
        Temp : Temp * 10 + Last - '0';
};

template<char... List>
inline constexpr value_type operator"" _value() noexcept
{
    return literal_parser<0U, List...>::value;
}

int main()
{
    std::cout << "value 1: " << 123456789012345678_value << std::endl;
    std::cout << "value 2: " << 1.23456789012345_value << std::endl;
    std::cout << "value 3: " << literal_parser<0U, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5'>::value << std::endl;

#if 0
    std::cout << "value 4: " << 1234567890123456789_value << std::endl;
    std::cout << "value 5: " << 1.234567890123456_value << std::endl;
    std::cout << "value 6: " << literal_parser<0U, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6'>::value << std::endl;
#endif
}
Run Code Online (Sandbox Code Playgroud)

这是gcc中的错误还是我错过了什么?

Mat*_*usz 3

我必须说你发现了一些让编译器疯狂的好角落案例:-) 对我来说 gcc 4.7.2 和 4.8 在编译过程中崩溃了。然而 clang(顶级版本)可以很好地编译整个代码,但使用的是 2.4GB RAM。该问题似乎与“.”的 ternaty 运算符有关。查看。如果您删除它并在 main() 中注释实数测试,那么一切都会编译得很好。

因此,回答您的问题时,您可能不会错过任何内容,并且 gcc 和 clang 可能需要根据您的情况修改其实现。