有没有办法在编译时实例化所有 c++ 模板大小
Is there a way to instantiate all the c++ template sizes at compile time?
下面的 c++/cli 模板正在工作,但似乎应该有一种方法可以进一步概括模板或添加一个可以在编译时创建模板实例的帮助程序。
在想类似 http://en.cppreference.com/w/cpp/utility/integer_sequence 的东西可能会起作用,但需要一些帮助者/实现器功能的帮助。
简化的主要内容以演示所需的语法与当前使用的语法:
int main(array<String^>^ args) {
// the actual number of possible char lengths is sparse (generally)
// but the API allows for 1-1024
List<int>^ varList = gcnew List<int>();
varList->Add(40);
varList->Add(80);
varList->Add(128);
SortedList<int, List<String^>^>^ allStrings = gcnew SortedList<int, List<String^>^>();
// want something like this, but the compiler complains that
// the template is invalid expectes compile-time constant expressions
for each(int key in varList) {
allStrings->Add(key, UpdateTest<key>());
}
// this works, but has 1024 lines of case N:
for each(int key in varList) {
switch (key) {
case 1: allStrings->Add(key, UpdateTest<1>());
case 2: allStrings->Add(key, UpdateTest<2>());
case 3: allStrings->Add(key, UpdateTest<3>());
//... all 1024 possible char[N] sizes...
case 1024: allStrings->Add(key, UpdateTest<1024>());
}
}
}
模板适用于 1024 交换机案例 N: 呼叫。 有没有办法让助手/实现者在没有案例的情况下实例化所有 1024 个?
template <std::size_t N> List<String^>^ APIwrapper::UpdateTest() {
typedef char CHARX[N]; // N valid for 1 to 1024
CHARX vals[MAXFIELDS];
// NATIVE C++ VendorAPI(short, void*) vals is the address of the word aligned destination data
int count = VendorAPI(N, &vals);
List<String^>^ retList = gcnew List<String^>();
for (int c = 0; c < count; c++) {
CHARX temp;
strncpy(temp, vals[c], N); // terminated char arrays
String^ x = gcnew String(temp);
retList->Add(x->Substring(0, N)->Trim());
}
return retList;
}
以下答案适用于c ++ 14,我不知道它是否与cli兼容。
您可以使用模板生成函数指针std::array
:
using UpdateTestPtr = decltype(&UpdateTest<0>);
// Struct used to generate the array's content.
template<typename Sequence>
struct UpdateTestArrayImpl;
// Specialization used to get the values in the integer sequence.
template<std::size_t... indices>
struct UpdateTestArrayImpl<std::integer_sequence<std::size_t,indices...>> {
static constexpr std::array<UpdateTestPtr,sizeof...(indices)> value{UpdateTest<indices>...};
};
// Factorise sequence creation
template<std::size_t N>
using UpdateTestArray = UpdateTestArrayImpl<std::make_index_sequence<N>>;
static constexpr std::size_t N = 512;
// The array is needed at runtime. Create a normal (not constexpr) instance.
static std::array<UpdateTestPtr,N> functionArray = UpdateTestArray<N>::value;
并将switch/case
转换为数组查找:
for each(int key in varList) {
allStrings->Add(key, functionArray[key]());
}
现场演示
某些编译器可能会产生"模板实例化深度"错误,具体取决于make_integer_sequence
的实现方式。递归深度的最大限制通常可以通过编译器选项增加。
不要使用模板执行此操作。
您正在使用模板将单个大块内存(CHARX vals[MAXFIELDS];
)转换为许多单独的字符串。相反,自己做。
List<String^>^ APIwrapper::UpdateTest(size_t size)
{
char* vals = new char[size * MAXFIELDS];
// NATIVE C++ VendorAPI(short, void*) vals is the address of the word aligned destination data
int count = VendorAPI(size, vals);
List<String^>^ retList = gcnew List<String^>();
char temp[1025]; // max size + 1.
for (int c = 0; c < count; c++)
{
// Instead of relying on the compiler to know that [1] should be 10 bytes in,
// [2] should be 20 bytes in, etc, do that yourself.
strncpy(temp, &vals[size * c], size);
temp[size] = ' '; // safety
String^ x = gcnew String(temp);
retList->Add(x->Trim());
}
delete [] vals;
return retList;
}
现在,话虽如此:这是一个不寻常的API。实际上,您正在传递一个内存块,以及每个字符串放置的步伐。这有点奇怪,但也只能通过每个步幅值检索一些数据???这很奇怪。我会检查如果始终使用 1024 作为步幅,供应商的 API 是否仍然会正确响应。
相关文章:
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 检查某些类型是否是模板类 std::optional 的实例化
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- 模板化类构造函数的模板实例化
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 受约束的成员函数和显式模板实例化
- 对显式实例化的模板函数的未定义引用
- [temp.variadic]中关于包扩展实例化的措辞