需要一种方法,使仅标题库中的任何类型的模板常数
Need a way to have templated constants of any type in a header only library
goals:
1. store constants with their assignments in a header
2. keep constants in a namespace (without using #define)
3. allow constants to be whatever precision is needed for the app
我正在尝试将所有常数保留在同一名称空间中的Header库。我决定取消#define
s并以正确的方式进行操作,例如使用:
namespace studio
{
namespace constant
{
const char* WHITE_SPACE = "nrt ";
}
}
希望这样的访问: studio::constant::WHITE_SPACE
这一切都很好,而且从我收集的东西来看,这样做为每个翻译单元创建其中一个,可能在链接过程中将其优化为一个实例。即使没有这样的优化,在这种情况下也可能还可以。
当我想在const char *以外添加其他类型的其他类型时,问题就会出现。例如,说我想允许浮动类型(双重或浮点)作为常数,但我想作为模板这样做,这样我就不必做这样的事情:
namespace studio
{
namespace constant
{
const char* WHITE_SPACE = "nrt ";
const float PI_FLOAT = 3.141592653589793;
const double PI_DOUBLE = 3.141592653589793;
}
}
所以我尝试使用模板类而不是名称空间,并带有静态函数,这些函数返回静态常数,例如:
namespace studio
{
template <class FloatType = float>
class constant
{
public:
static const char* white_space_chars() {
static const char* whiteSpaceChars = "nrt ";
return whiteSpaceChars;
}
static const FloatType pi() {
static const FloatType _pi = 3.141592653589793;
return _pi;
}
}
}
然后将其访问:studio::constant<float>::pi()
,但是现在我有一个问题,如果我想要一个const char,即使它们与浮子无关,我必须提供模板参数,但必须像这样访问它们: studio::constant<float>::white_space_chars()
因为 studio::constant::white_space_chars()
即使我指定了一个默认的模板参数,显然不起作用,这显然仅适用于类。C 不允许在功能模板上默认。
所以现在我能看到的唯一方法是拥有studio :: constand_char,studio :: constant_float,studio :: constant_int等。这很荒谬,对吗?
我真正想要的就是在名称空间中定义我的定义...
您知道一种更好的方法来完成我要做的事情吗?可以在studio ::常数命名空间中使用不同类型的变量,而无需强迫库的用户为每个模板参数指定类型?最好不使用C 11向后兼容。
将模板移至实际使用的静态方法上:
namespace studio
{
class constant
{
public:
static const char* white_space_chars() {
return "nrt ";
}
template <class FloatType = float>
static const FloatType pi() {
return FloatType(3.141592653589793);
}
};
}
然后您可以这样做:
float flt_pi = studio::constant::pi();
double dbl_pi = studio::constant::pi<double>();
我想这可以通过具有覆盖定义来完成:
#ifndef STUDIO_FLOAT_TYPE
typedef float STUDIO_FLOAT_TYPE;
#endif
namespace studio
{
namespace constant
{
const char* WHITE_SPACE = "nrt ";
const STUDIO_FLOAT_TYPE PI = 3.141592653589793;
}
}
将允许用户在包含库标头之前覆盖浮点类型。至少只有一个定义,它仍然具有默认值。
因为肯定会在其他标题中使用这样的定义,所以我想将所有可自定义的定义在单个单独的库标题中所指的单个标题中定义可能很不错。
供将来参考,在C 14中,您可以做:
template <typename T>
const T PI = T(3.141592653589793);
请参阅变量模板。
作为一个例子:
// header.h
namespace constant
{
template <typename T>
constexpr T PI = T(3.141592653589793);
}
void foo();
// foo.cpp
#include <iostream>
#include "header.h"
void foo() {
std::cout << constant::PI<int> << std::endl;
}
// main.cpp
#include <iostream>
#include "header.h"
int main()
{
std::cout << constant::PI<float> << std::endl;
foo();
}
这给出了输出:
3.14159
3
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 如何在不产生任何垃圾的情况下获得C中的像素
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- C++映射有2个键,这样任何1个键都可以用来获取值
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- RtlCaptureStackBackTrace未捕获任何帧
- 链表c++插入,所有情况都已检查,但没有任何工作
- C++模板函数,用于比较任何无符号整数和有符号整数
- 对于C++,方括号中的标题必须总是在引号中的标题之上吗
- 库标题在标题中不可见,但在 cmake build 下.cpp文件中完全可见.为什么?
- Arduino millis() - millis() 怎么能等于 0 以外的任何东西?
- 尝试摆脱任何堆内存分配
- 是否有任何C++功能可以对地图进行排序?
- 打印时有二叉树问题.用户输入不打印任何内容
- Gtkmm 窗口为空白,不显示任何小部件或标题
- 为什么GDB(或任何调试器)逐步进入标题
- 需要一种方法,使仅标题库中的任何类型的模板常数
- 为什么在C语言的标题中使用"#"符号?为什么不是任何其他符号?