代码之家  ›  专栏  ›  技术社区  ›  SPWorley

compiletime常量索引是否指向compiletime常量数组本身compiletime常量?

  •  2
  • SPWorley  · 技术社区  · 17 年前

    我正在尝试玩一些复杂的游戏,这些游戏让C++编译器在编译时合成常数字符串的哈希值。这将使我用一个标识符替换字符串,从而大大节省代码大小和复杂性。

    为了编程的清晰性和易用性,如果我能在compiletime使用简单的内联字符串(如“hello”)来检查和计算,那将是非常棒的,这些字符串是compiletime常量字符的compiletime常量指针。

    如果我能在compiletime索引到这些,我就可以制作一个模板元程序来做我想做的事情。但是目前还不清楚C++标准是否将CT常数数组的CT常数作为CT常数来处理。

    换个角度问,

     const char v="Hello"[0];
    

    是非常有效的C++(和C)。但是 值v是编译时常量吗?

    我已经相信答案是否定的,但实际上有些编译器在没有任何警告的情况下接受它,更不用说错误了。例如,以下编译和运行甚至没有一个来自英特尔C++编译器的警告:

    #include <iostream>
    const char value="Hello"[0];
    template<char c>  void printMe()
    {
      std::cout << "Template Val=" << c << std::endl;
    }
    
    int main()
    {
      const char v='H';
      printMe<'H'>();
      printMe<v>();
      printMe<value>(); // The tricky and interesting case!
    }
    

    然而,微软的编译器根本不会编译,它给出了一个合理一致的错误消息,关于使用带有内部链接的对象的模板。

    我怀疑我的问题的答案是“不,您不能假设任何数组引用,即使是在compiletime中对具有常量索引的常量数组的引用也是常量”。这是否意味着英特尔编译器的成功执行是英特尔编译器中的一个错误?

    3 回复  |  直到 17 年前
        1
  •  2
  •   Chris Jester-Young    17 年前

    它也不适用于gcc。

    然而 ,在语言遵从性的观点之外,编译器优化程序确实将其视为字符常量,这非常好。我利用这个事实允许预处理器生成字符常量(通过使用 *#foo )见 http://cvs.openbsd.org/cgi-bin/query-pr-wrapper?full=yes&numbers=1652 在文件中 hdr.h . 用这个宏,你可以写

    DECR(h, e, l, l, o)
    

    而不是

    DECR('h', 'e', 'l', 'l', 'o')
    

    在我看来,可读性更强。-)

        2
  •  1
  •   Robert Gould    17 年前

    很好的问题,是的,这是可以做到的,它与标准很好,它将在微软,海合会,英特尔工作,问题是你有语法错误:)

    一秒钟我会做一个样品… 好了,给你。这个示例是有效的C++,我经常使用它,但实际上大多数程序员不知道如何正确地使用它。

    template<char* MSG>
    class PrintMe
    {
    public:
        void operator()()
        {
            printf(MSG);
        }
    };
    
    char    MyMessage[6] = "Hello"; //you can't use a char*, but a char array is statically safe and determined at compiletime
    
    int main(int argc, char* argv[])
    {
        PrintMe<MyMessage> printer;
        printer();
        return 0;
    }
    
        3
  •  0
  •   MSalters    17 年前

    与此相关的区别是“整型常量表达式”和仅仅编译时常量之间的区别。3.0”是一个编译时常数。int(3.0)”也是一个编译时常量。但只有“3”是冰。见5.19

    More details at boost.org