c++使用constexpr函数的形参作为模板的常量
C++ use parameter of a constexpr function as constant for template
由于c++不允许模板类具有"auto"类型的值参数模板(您可以template<int N>
或template <EnumFoo E>
,但您不能真正匹配两者),我想为类型+值编写一个包装器。
真正的问题是,没有人想写值和它的类型,我试着写一个函数有点类似于make_unique
,除了创建一个std::unique
对象,它应该有一个返回类型作为包装器。
我写的是:
enum class E1
{
First
};
enum class E2
{
First
};
/*
* Here, the goal is to be able to have a ClassTemplatedOnAnyValueNoMatterType
* you can template on E1::First, or E2::First, and the template instances
* are NOT the same one.
* We need a wrapper (EnumValueWrapper).
*/
template <typename T>
struct ClassTemplatedOnAnyValueNoMatterType
{};
template <typename T, T Value>
struct EnumValueWrapper
{
static const T value = Value;
};
/*
* Since it's annoying to write EnumValueWrapper<E1, E1::First>, we'd like to
* have a utility function that generates the EnumValueWrapper type.
*/
template <typename T>
// does NOT compile, t outside of function body
constexpr auto makeEnumValueWrapper(const T t) -> EnumValueWrapper<T, t>;
typedef ClassTemplatedOnAnyValueNoMatterType<decltype(makeEnumValueWrapper(E1::First))> MyClass;
int main()
{
MyClass s;
}
这不能编译,我想知道是否有任何替代方案,使用尽可能少的宏(没有MACRO(E1, First)
,因为我不仅希望能够使用文字,还希望能够使用int类型)。
有什么好主意吗?
这不会解决你的问题吗:
template <typename T>
struct Dummy
{
template <T t>
friend EnumValueWrapper<T, t> makeEnumValueWrapper();
};
template struct Dummy<E1>;
typedef ClassTemplatedOnAnyValueNoMatterType<decltype(makeEnumValueWrapper<E1::First>())> MyClass;
您仍然需要在每个相关类上显式实例化Dummy,但是MyClass的typedef没有多余的类型/值规范。
等待c++的后续迭代。
建议允许类型参数依赖于值参数的类型。到目前为止,还没有一个通过审查。
如果等待听起来不是个好主意,那就深入到标准化过程中,并自己将其添加到c++中。
在此之前,继续将template
常量的类型传递给template
.
我知道你不喜欢宏,但一个非常简单的解决方案是:
#define WRAP_VALUE(...) EnumValueWrapper<decltype(__VA_ARGS__), (__VA_ARGS__)>
typedef ClassTemplatedOnAnyValueNoMatterType<WRAP_VALUE(E1::First)> MyClass;
我不相信没有样板没有宏是不可能做到的。我的理由是,如果你不使用宏,你只能使用你的"值"表达式一次——要么作为函数参数,要么作为模板参数,要么作为decltype的一部分。两者单独都没有用。如果您将其用作函数参数,则无法将其值作为常量表达式检索。首先,您不能将它用作模板形参,因为没有办法声明一个接受任意类型值的模板形参——除非另一个模板形参表示该类型。最后,如果在decltype()中使用它,该值将丢失。
宏使用__VA_ARGS__
而不是单个参数,以便您可以在表达式中使用逗号。例如,当作为WRAP_VALUE(std::is_same<float, bool>::value)
调用时,预处理器会抱怨宏调用时带有两个参数。
- 使用mem_fun_ref if成员函数需要多个形参
- 通过类的模板形参特化成员模板结构
- 非类型引用形参/实参
- 哪个模板形参在boost::shared_ptr构造函数中使用一个原始指针
- 如何确保迭代器模板形参与模板类的模板形参具有相同的数据类型
- 如何在编译时通过模板形参默认值的名称/指针获取函数的类型
- c++:候选模板被忽略:模板形参显式指定的参数无效
- c++中作为形参的指针
- 哪种方法更适合为函数提供编译时间常数?函数实参与模板形参
- 包含void*结构的函数的Const正确性和形参
- 传递boost::函数,该函数接受一个模板实参作为默认为NULL的形参
- 将右值引用形参强制转换为右值引用
- 给引用形参赋值使对象无效
- 当实参是初始化列表而形参是引用时,重载解析
- const整型模板形参的条件
- 定义常量数组用作模板形参
- c++形参是一个指向常量对象的指针,但不返回更新后的对象
- 为什么标准不允许在模板形参列表中初始化依赖于常量的类型
- c++使用constexpr函数的形参作为模板的常量
- 对具有相同形参类型但具有不同常量限定符的std::vector进行强制转换