假设我们有0.33,我们需要输出"1/3".
如果我们有"0.4",我们需要输出"2/5".
我们的想法是让人们可读,让用户理解"y部分中的x部分",作为理解数据的更好方式.
我知道百分比是一个很好的替代品,但我想知道是否有一个简单的方法来做到这一点?
假设您有一个为您的应用程序生成一些安全性令牌的函数,例如一些哈希盐,或者可能是对称或非对称密钥.
现在假设您在C++中将此函数作为constexpr,并根据某些信息(例如,构建号,时间戳,其他内容)为构建生成密钥.
你是一个勤奋的程序员,确保并以适当的方式调用它,以确保它只在编译时被调用,因此死剥离器从最终的可执行文件中删除代码.
但是,您无法确定其他人是否会以不安全的方式调用它,或者编译器可能不会删除该功能,然后您的安全令牌算法将成为公共知识,使其成为公共知识更容易让攻击者猜测未来的令牌.
或者,除了安全性之外,假设该函数需要很长时间才能执行,并且您希望确保它在运行时期间永远不会发生,并且会给最终用户带来糟糕的用户体验.
有没有办法确保在运行时永远不会调用constexpr函数?或者,在运行时抛出一个断言或类似的东西就可以了,但不像编译错误那样明显.
我听说有一些方法涉及抛出一个不存在的异常类型,所以如果constexpr函数没有被删除,你会得到一个链接器错误,但是听说这只适用于某些编译器.
远程相关的问题:强制constexpr在编译时进行评估
我正在尝试编写一个包含变量的类,该变量的类型将被选择为能够包含值的最小值.
我的意思是:
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模板.是否有其他方法可以将变量(在编译期间应该可用)传递给类?
在2003年 - 是的,2003年 - 范德沃德和约瑟特在他们的书"C++模板"(第40页)中写道:
无法使用浮点文字(和简单的常量浮点表达式)作为模板参数具有历史原因.因为没有严重的技术挑战,所以在未来的C++版本中可能会支持这一点.
但即使在C++ 11下,这仍然无效:
template<double D> //error
void foo() {}
Run Code Online (Sandbox Code Playgroud)
为什么没有添加?
我有问题理解以下段落Per C++ 11 Standard N3485 Section 14.1.7.我认为理解基本原理而不是记住事实更为重要.
非类型模板参数不应声明为具有浮点,类或void类型.
[例如:Run Code Online (Sandbox Code Playgroud)template<double d> class X; // error template<double* pd> class Y; // OK template<double& rd> class Z; // OK- 末端的例子]
我对此规则有一些疑问:
有没有理由为什么floating point类型不能用作模板参数?这背后的理由是什么?我知道在C++ 11之前就是这样,对于C++ 11标准来说也是如此.
为什么它是确定使用pointer或reference浮点类型为非模板参数,而不是原始的浮点类型?这里最大的区别是什么?
谢谢您的帮助.
非类型模板参数显然不是类型,例如:
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,因为这意味着内部联动,这基本上意味着,该行不会编译.我们可以通过声明绕过t的const extern.这本身可能有点奇怪,但真正令我惊讶的是为什么这是不可能的:
Foo<Triple { 1, 2, 3 }> f;
Run Code Online (Sandbox Code Playgroud)
我们从编译器得到了一个非常好的错误:
error:
Triple{1, 2, 3}不是类型的有效模板参数,const Triple&因为它不是左值.
我们不能Triple在模板中按值指定,因为这是不允许的.但是,我无法理解这一小段代码的真正问题.不允许使用结构作为值参数的原因是什么.如果我可以使用三个ints,为什么不使用三个整数的结构?如果它只有普通的特殊成员,那么它在处理方面不应该只是三个变量.
我想创建一个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)
还有其他方法可以做到这一点吗?
我可以强制编译器只接受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不起作用.
那是完全不合逻辑的.
我正在使用一个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?
我知道为什么我不能使用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) 我的类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)