相关疑难解决方法(0)

如何将浮点数转换为人类可读的分数?

假设我们有0.33,我们需要输出"1/3".
如果我们有"0.4",我们需要输出"2/5".

我们的想法是让人们可读,让用户理解"y部分中的x部分",作为理解数据的更好方式.

我知道百分比是一个很好的替代品,但我想知道是否有一个简单的方法来做到这一点?

language-agnostic algorithm numbers

100
推荐指数
11
解决办法
5万
查看次数

如何确保constexpr函数从未在运行时调用?

假设您有一个为您的应用程序生成一些安全性令牌的函数,例如一些哈希盐,或者可能是对称或非对称密钥.

现在假设您在C++中将此函数作为constexpr,并根据某些信息(例如,构建号,时间戳,其他内容)为构建生成密钥.

你是一个勤奋的程序员,确保并以适当的方式调用它,以确保它只在编译时被调用,因此死剥离器从最终的可执行文件中删除代码.

但是,您无法确定其他人是否会以不安全的方式调用它,或者编译器可能不会删除该功能,然后您的安全令牌算法将成为公共知识,使其成为公共知识更容易让攻击者猜测未来的令牌.

或者,除了安全性之外,假设该函数需要很长时间才能执行,并且您希望确保它在运行时期间永远不会发生,并且会给最终用户带来糟糕的用户体验.

有没有办法确保在运行时永远不会调用constexpr函数?或者,在运行时抛出一个断言或类似的东西就可以了,但不像编译错误那样明显.

我听说有一些方法涉及抛出一个不存在的异常类型,所以如果constexpr函数没有被删除,你会得到一个链接器错误,但是听说这只适用于某些编译器.

远程相关的问题:强制constexpr在编译时进行评估

c++ constexpr c++11 c++14

16
推荐指数
4
解决办法
2033
查看次数

根据浮点数选择最小整数类型

我正在尝试编写一个包含变量的类,该变量的类型将被选择为能够包含值的最小值.

我的意思是:

class foo {
 "int type here" a;
}
Run Code Online (Sandbox Code Playgroud)

我遇到了自动选择一个足够大的变量类型来保存指定的数字.由于使用boost库的困难,我继续使用模板建议.

这会将代码转换为:

template<unsigned long long T>
class foo {
 SelectInteger<T>::type a;
}
Run Code Online (Sandbox Code Playgroud)

但是,我的问题来自于变量的大小是浮点变量和整数相乘的结果.因此,我希望能够做到的是:

template<unsigned long long T, double E>
class foo {
 SelectInteger<T*E>::type a;
}
Run Code Online (Sandbox Code Playgroud)

但由于模板不适用于浮点变量(参见此处),我无法传入E模板.是否有其他方法可以将变量(在编译期间应该可用)传递给类?

c++ templates c++11

14
推荐指数
1
解决办法
297
查看次数

为什么不允许double作为非类型模板参数?

在2003年 - 是的,2003年 - 范德沃德和约瑟特在他们的书"C++模板"(第40页)中写道:

无法使用浮点文字(和简单的常量浮点表达式)作为模板参数具有历史原因.因为没有严重的技术挑战,所以在未来的C++版本中可能会支持这一点.

但即使在C++ 11下,这仍然无效:

template<double D> //error
void foo() {}
Run Code Online (Sandbox Code Playgroud)

为什么没有添加?

c++ templates c++11

13
推荐指数
3
解决办法
2136
查看次数

理解非类型模板参数

我有问题理解以下段落Per C++ 11 Standard N3485 Section 14.1.7.我认为理解基本原理而不是记住事实更为重要.

非类型模板参数不应声明为具有浮点,类或void类型.
[例如:

template<double d> class X; // error
template<double* pd> class Y; // OK
template<double& rd> class Z; // OK
Run Code Online (Sandbox Code Playgroud)

- 末端的例子]

我对此规则有一些疑问:

  1. 有没有理由为什么floating point类型不能用作模板参数?这背后的理由是什么?我知道在C++ 11之前就是这样,对于C++ 11标准来说也是如此.

  2. 为什么它是确定使用pointerreference浮点类型为非模板参数,而不是原始的浮点类型?这里最大的区别是什么?

谢谢您的帮助.

c++ templates c++11

12
推荐指数
1
解决办法
1046
查看次数

为什么结构不能作为模板非类型参数传递?

非类型模板参数显然不是类型,例如:

template<int x>
void foo() { cout << x; }
Run Code Online (Sandbox Code Playgroud)

除了int那种情况还有其他选择,我想谈谈这个很好的答案.

现在,有一件事让我感到困惑:结构.考虑:

struct Triple { int x, y, z; };

Triple t { 1, 2, 3 };

template<Triple const& t>
class Foo { };
Run Code Online (Sandbox Code Playgroud)

现在,使用普通的非类型引用语义,我们可以编写:

Foo<t> f;
Run Code Online (Sandbox Code Playgroud)

什么是这里值得注意的是,t 不能constexpr甚至const,因为这意味着内部联动,这基本上意味着,该行不会编译.我们可以通过声明绕过tconst extern.这本身可能有点奇怪,但真正令我惊讶的是为什么这是不可能的:

Foo<Triple { 1, 2, 3 }> f;
Run Code Online (Sandbox Code Playgroud)

我们从编译器得到了一个非常好的错误:

error:Triple{1, 2, 3}不是类型的有效模板参数,const Triple&因为它不是左值.

我们不能Triple在模板中按值指定,因为这是不允许的.但是,我无法理解这一小段代码的真正问题.不允许使用结构作为值参数的原因是什么.如果我可以使用三个ints,为什么不使用三个整数的结构?如果它只有普通的特殊成员,那么它在处理方面不应该只是三个变量.

c++ templates c++11

11
推荐指数
3
解决办法
5279
查看次数

为数值数组创建别名

我想创建一个std::array只有数字类型的别名

template<typename T, std::size_t n, T = std::is_arithmetic<T>::value>
using NumericArray = std::array<T, n>;
Run Code Online (Sandbox Code Playgroud)

这适用于整数

NumericArray<int, 2> i{1, 2};
Run Code Online (Sandbox Code Playgroud)

但是,如果我想要一个浮点数或双精度,我会因非类型模板参数而出错

NumericArray<float, 2> f{1.0f, 2.0f};
Run Code Online (Sandbox Code Playgroud)

还有其他方法可以做到这一点吗?

c++ c++11 c++14

9
推荐指数
2
解决办法
409
查看次数

强制编译器只接受编译时参数(浮点)

我可以强制编译器只接受constexpr函数的一个或非变量输入吗?

我正在寻找只允许编译函数的时间值.使用模板或任何其他方法.

这里有一个int模板的工作示例.doubles 的问题是它们不能用作模板参数.

#include <iostream>

template <double x>
void show_x()
{
    std::cout<<"x is always "<<x<<" in the entire program."<<std::endl;
}

int main()
{
    show_x<10.0>();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

错误:'double'不是模板非类型参数的有效类型


更新

对于那些将此问题标记为重复的人,我不得不说:

我问问题

如何解决问题A?

解决方案B不适用于问题A,我需要另一种解决方案

然后你链接我为什么解决方案B不起作用.

那是完全不合逻辑的.

c++ templates c++11

7
推荐指数
1
解决办法
597
查看次数

第一个模板类型的模板参数

我正在使用一个API,它将带有单个参数的函数作为回调.回调采用某种类型的单个参数,为简单起见,我会说它返回一个bool.我试图整理的主要内容是范围检查功能.我的直觉是写这样的东西:

template<class T, T min, T max>
constexpr bool in_range(T val) {
    return (val >= min && val <= max);
}

static_assert(in_range<float, 0.0f, 1.0f>(0.5f), "doesn't work")
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用,所以我默认以这种方式创建一个函数.

template<class T>
std::function<bool(T)> in_range(T min, T max) {
    auto test = [min, max](T val) {
        return (val >= min && val <= max);
    };
    return test;
}


assert(in_range<float>(0.0f, 1.0f)(0.5f))
Run Code Online (Sandbox Code Playgroud)

有没有办法以第一个函数的形式更多地编写函数,所以我不依赖std::function于运行时生成的lambdas?

c++ templates callback constexpr c++11

5
推荐指数
1
解决办法
157
查看次数

获取浮动模板参数工作的"hack"编译,但在g ++和clang上都是segfaulted

我知道为什么我不能使用float作为模板参数以及如何通过分子/分母对设置模板类的静态const float成员.但是我正在尝试基于reinterpret_cast的另一个"hack"到来自IEEE754十六进制写入的"emule"浮点模板参数.

这是一小段代码:

#include <iostream>
#include <cstdint>

template <uint32_t T>
struct MyStruct
{
    static const float value;
};

template <uint32_t T>
const float MyStruct<T>::value = *reinterpret_cast<float*>(T);

int main()
{
    typedef MyStruct<0x40490fdb> Test;
    std::cout << Test::value << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我编译它...

g++ -Wall -pedantic main.cpp -std=c++0x -g
Run Code Online (Sandbox Code Playgroud)

没有任何警告.

并且它分裂......

brugelca@artemis:~/workspace/draft$ ./a.out 
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)

这是valgrind输出:

brugelca@artemis:~/workspace/draft$ valgrind ./a.out
==10871== Memcheck, a memory error detector
==10871== Copyright (C) 2002-2012, and GNU GPL'd, by Julian …
Run Code Online (Sandbox Code Playgroud)

c++ templates reinterpret-cast c++11

4
推荐指数
1
解决办法
446
查看次数

C++ 11模板中的一个参数可以依赖于另一个吗?

我的类SimRank有两个浮点常量参数,C和D.我希望它们是静态constexprs,而不是const实例成员.但我也希望让用户选择哪一种使用浮点,float对尺寸或double精密.

显而易见的方法是这样的:

template<typename FP, int _K, FP _C, FP _D>
class SimRank {
    static constexpr int K = _K;
    static constexpr FP C = _C;
    static constexpr FP D = _D;
};

template<int _K, float _C, float _D>
class SimRank<float> {};

template<int _K, double _C, double _D>
class SimRank<double> {};

int main() {
    SimRank<5, 0.8, 0> sd; // uses double
    SimRank<10, 0.6f, 0.05f> sf; // uses float
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试这个时,gcc会打印许多错误消息,所以显然语法不存在.我也做不了这样的事情:

template<typename FP> template<int …
Run Code Online (Sandbox Code Playgroud)

c++ templates typename c++11

2
推荐指数
1
解决办法
141
查看次数