下面的 c++/cli 模板可以正常工作,但似乎应该有一种方法可以进一步概括模板或添加一个可以在编译时创建模板实例的助手。
我在想 http://en.cppreference.com/w/cpp/utility/integer_sequence可能有效,但需要帮助程序/实现程序功能的一些帮助。
简化 main 以演示所需语法与当前使用的语法:
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 switch case 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); // \0 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
的实现方式。递归深度的最大限制通常可以通过编译器选项增加。
关于c++ - 有没有办法在编译时实例化所有 C++ 模板大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46865317/