C++只能用作 constexpr 变量的类型
C++ type that can only be used as constexpr variable
我有一个库类型,它只应该用作全局变量,并且必须进行链接器初始化(即它必须在静态初始化时间之前具有正确的初始值(。我有充分的理由认为,如果我做以下两件事之一,我将得到我需要的东西:
- 使其成为 POD 类型,将用户提供的成员放在第一位,并信任用户将正确数量的表达式传递给
Type var = { expr, expr };
语法。 - 使实现私有,提供
constexpr
构造函数,并依赖于用户将所有实例声明为constexpr
。
这些都不好,因为它取决于用户不会把事情搞砸。
除了宏魔术之外,有没有办法强制constexpr
类型的所有实例?
创建一个
template<Type1 value1, Type2 value2>
constexpr MyType make_MyTYpe(/* No args */)
{
return MyType(value1, value2); // call the (private) constexpr constructor
}
如果您的类型仅提供 const 方法,则用户必须使用const
对象。
const MyType myobject = make_MyType<4, 2>();
myobject
const
constexpr
.
您无法
阻止的是用户向创建的任何实例声明const&
。但是,您可以阻止复制和移动实例。现在,您只需要强制创建的所有实例都是在需要常量表达式的上下文中创建的。
这是一种奇怪的强制方法:让所有实例都static constexpr
类(模板(的成员。
然后,用户提供了一种获取"变量"的构造函数参数的方法。
struct constructor_params
{
int i;
double d;
};
用户提供的实例必须在常量表达式中可用,以便初始化static constexpr
成员。
为了创建不同的实例,我们需要某种标记值来创建类模板的不同实例化,该类模板包含将用作变量实例的static constexpr
成员。我选择结合标签值和提供constructor_params
参数的方式,让用户提供工厂函数或类型来创建参数。
首先,您只想包含以下constexpr
实例的变量类型:
// forward declarations useful for friendship
template<class T>
struct make_variable_by_type;
template<constructor_params(*fptr)(void)>
struct make_variable_by_func;
struct the_variable
{
the_variable(the_variable const&) = delete;
the_variable(the_variable&&) = delete;
private:
constexpr the_variable(constructor_params) {}
template<class T>
friend struct make_variable_by_type;
template<constructor_params(*fptr)(void)>
friend struct make_variable_by_func;
};
为了让用户访问两种方式来创建具有一个名称的变量,有一个重载的make_variable
函数:
template<constructor_params(*fptr)(void)>
struct make_variable_by_func
{
static constexpr the_variable value{fptr()};
};
template<constructor_params(*fptr)(void)>
const the_variable make_variable_by_func<fptr>::value;
template<class T>
struct make_variable_by_type
{
static constexpr the_variable value{T::make()};
};
template<class T>
const the_variable make_variable_by_type<T>::value;
template<class T>
constexpr the_variable const& make_variable()
{
return make_variable_by_type<T>::value;
}
template<constructor_params(*fptr)(void)>
constexpr the_variable const& make_variable()
{
return make_variable_by_func<fptr>::value;
}
现在,两个使用示例。一个具有用于创建constructor_params
的constexpr
函数,另一个具有本地类型(函数作用域是需要从类型创建的原因(。
constexpr constructor_params make_my_variable()
{
return {42, 21.0};
}
constexpr auto& x = make_variable<make_my_variable>();
int main()
{
struct make_my_other_variable
{
static constexpr constructor_params make()
{
return {1, 2};
}
};
constexpr auto& x = make_variable<make_my_other_variable>();
}
相关文章:
- c++类声明时,相同的例程,不同的成员变量类型
- 如何为 c++ 的不同变量类型的结构元素创建动态数组?
- 创建类似于布尔值的变量类型
- std::cin 从控制台获取两种不同的变量类型,'storing'以后使用第二种类型?
- 如何使用变量模板比较 C++ 17 中的变量类型?
- 是否有一个库可以检查C++中的变量类型?
- 与不同变量类型相比,用于变量的 Clang AST 匹配器
- 继承类中的 C++ 成员变量类型重写
- 如何在编译器时动态获取元组内的变量类型C++?
- 在C++中动态分配变量类型
- 用于浮点值的最佳变量类型
- 定义变量类型
- 错误 - 变量类型 "X" 是一个抽象类 - c++
- 在函数 (c++) 中分配变量类型和大小数组
- 具有容器变量类型的类模板
- 获取变量类型名称
- 沿枚举 c++ 返回变量类型
- 是否可以通过模板指定抽象类变量类型
- 什么是变量类型位(32)
- C++ 在知道变量类型之前使用自动定义的变量