这对我来说似乎不可能,但StackOverflow已经解决了以前对我来说似乎不可能的事情,所以在这里:
我在文件名和ID之间有一个预定义的映射,我希望能够在编译时将__FILE__
映射到它的id,如果可能的话。
对于粗略的解释感到抱歉,我希望有一个例子可以帮助:
在编译过程开始之前通过某些脚本生成的ID:
#define _FILE_IDS_MAIN_CPP 1
#define _FILE_IDS_HELPER_CPP 2
#define _FILE_IDS_HELPER_HPP 3
在代码中,我希望能够做到这样的事情:
printf("%d", GET_FILEID_MACRO(__file__));
答案 0 :(得分:0)
为了帮助您入门,您可以使用自C ++ 11以来可用的constexpr
函数来对文件名字符执行某些计算。例如,如果您只是让字符串长度为您的ID,则可以:
template <unsigned int N>
constexpr unsigned int FileID(char const (&a)[N])
{
// your computation goes here
return N;
}
#include <iostream>
template <unsigned int N> void print()
{
std::cout << "Static value: " << N << "\n";
}
int main()
{
print<FileID(__FILE__)>();
}
包含print
模板作为编号在编译时计算的证明。
以此作为起点,您可以将FileID
更改为某种哈希函数,或者可能更改为静态地图查找 - 这当然是可能的,尽管可能相当冗长。我确定有人已经这样做了。
答案 1 :(得分:0)
拥有C ++ 11:
#include <cstring>
#include <iostream>
constexpr unsigned id(const char* file) {
return (std::strcmp(file, "One") == 0) ? 1 : 0;
}
template<unsigned>
void print() {
std::cout << "Zero\n";
}
template<>
void print<1>() {
std::cout << "One\n";
}
int main () {
print<id("Zero")>();
print<id("One")>();
return 0;
}
不确定strcmp在constexpr函数中是否有效并且在@MSalters链接中的第二个答案之后:
#include <iostream>
// Code from @Robert Mason
// =======================
constexpr bool static_strequal_helper(const char * a, const char * b, unsigned len) {
return (len == 0) ? true : ((*a == *b) ? static_strequal_helper(a + 1, b + 1, len - 1) : false);
}
template <unsigned N1, unsigned N2>
constexpr bool static_strequal(const char (&str1)[N1], const char (&str2)[N2]) {
return (N1 == N2) ? static_strequal_helper(&(str1[0]), &(str2[0]), N1) : false;
}
// End
template <unsigned N>
constexpr unsigned id(const char (&file)[N]) {
return (static_strequal(file, "One")) ? 1 : 0;
}
template<unsigned>
void print() {
std::cout << "Zero\n";
}
template<>
void print<1>() {
std::cout << "One\n";
}
int main () {
print<id("Zero")>(); // Prints Zero
print<id("One")>(); // Prints One
print<id(__FILE__)>(); // Prints Zero - Is __FILE__ always an array?
return 0;
}