Ошибка использования constexpr в качестве параметра шаблона в том же классе - PullRequest
6 голосов
/ 13 ноября 2011

Если я пытаюсь скомпилировать следующий код C ++ 0x, я получаю сообщение об ошибке:

template<int n> struct foo { };

struct bar {
    static constexpr int number() { return 256; }

    void function(foo<number()> &);
};

В gcc 4.6.1 появляется сообщение об ошибке:

test.cc:6:27: error: ‘static constexpr int bar::number()’ used before its definition
test.cc:6:28: note: in template argument for type ‘int’

В clang 2.8 появляется сообщение об ошибке:

test.cc:6:20: error: non-type template argument of type 'int' is not an integral
      constant expression
        void function(foo<number()> &);
                          ^~~~~~~~
1 error generated.

Если я переместу функцию constexpr в базовый класс, она будет работать в gcc и выдает то же сообщение об ошибке в clang:

template<int n> struct foo { };

struct base {
    static constexpr int number() { return 256; }
};

struct bar : base {
    void function(foo<number()> &);
};

Является ли код неправильным, или это ограничение или ошибка в реализации C ++ 0x в gcc 4.6?Если код неправильный, почему он неправильный, и какие пункты стандарта C ++ 11 говорят, что он неправильный?

Ответы [ 2 ]

5 голосов
/ 13 ноября 2011

В C ++ встроенные определения функций-членов для класса анализируются только после анализа каждого объявления в классе. Следовательно, в вашем первом примере компилятор не может увидеть определение number() в точке, где объявлено function().

(Ни одна выпущенная версия clang не поддерживает оценку функций constexpr, поэтому ни один из ваших тестов не будет там работать).

1 голос
/ 08 декабря 2012

У меня схожая ошибка со следующим кодом:

struct Test{
     struct Sub{constexpr Sub(int i){}};
    static constexpr Sub s=0;
};

"ошибка: 'constexpr Test :: Sub :: Sub (int)' вызван в константном выражении" в gcc 4.7.1. Пока это успешно скомпилируется:

struct Sub{constexpr Sub(int i){}};
struct Test{
    static constexpr Sub s=0;
};
...