2016-09-21 5 views
3

Учитывая кодСтранные ошибки constexpr TypeID

#include <typeinfo> 
#include <type_traits> 

struct A {}; 
struct B {}; 

static_assert(&typeid(A), ""); // Fine 
static_assert(&typeid(B), ""); // Fine 
static_assert(&typeid(A) != nullptr, ""); // Fine 
static_assert(&typeid(B) != nullptr, ""); // Fine 

constexpr auto const * tA = &typeid(A); 
constexpr auto const * tB = &typeid(B); 
using T = decltype(tA); 
using T2 = decltype(tB); 
static_assert(std::is_same<T, T2>::value, ""); // Fine, identical types! 
static_assert(tA == tA, ""); // Fine (comparing values of identical type) 
static_assert(tB == tB, ""); // Fine (comparing values of identical type) 
static_assert(tA != tB, ""); // Error: comparing values of identical type 
          //  suddenly not constexpr? 

Я получаю следующее сообщение об ошибке с Clang:

$ clang++ -std=c++1z test.cpp -o test 
test.cpp:19:18: error: static_assert expression is not an integral constant expression 
static_assert(tA != tB, ""); // Error: comparing values of identical type not constexpr? 
      ~~~^~~~~ 
1 error generated. 

И GCC:

$ g++-6.3.0 -std=c++1z test.cpp -o test 
test.cpp:19:1: error: non-constant condition for static assertion 
static_assert(tA != tB, ""); // Error: comparing values of identical type not constexpr? 
^~~~~~~~~~~~~ 
test.cpp:19:18: error: '(((const std::type_info*)(& _ZTI1A)) != ((const std::type_info*)(& _ZTI1B)))' is not a constant expression 
static_assert(tA != tB, ""); // Error: comparing values of identical type not constexpr? 
      ~~~^~~~~ 

Это не имеет значения, если я использую void вместо auto для tA и tB. Только изменения вывода НКУ-s немного:

$ g++-6.3.0 -std=c++1z test.cpp -o test 
test.cpp:19:5: error: non-constant condition for static assertion 
    static_assert(tA != tB, ""); // Error: comparing values of identical type not constexpr? 
    ^~~~~~~~~~~~~ 
test.cpp:19:22: error: '(((const void*)(& _ZTI1A)) != ((const void*)(& _ZTI1B)))' is not a constant expression 
    static_assert(tA != tB, ""); // Error: comparing values of identical type not constexpr? 
       ~~~^~~~~ 

Может кто-то пожалуйста, объясните, почему только последний static_assert не удается скомпилировать, в то время как другие не компилировать и передать?

+3

Мне кажется, что ссылка, возвращаемая 'typeid', не является constexpr, поэтому возвращаемое значение не является constexpr. Непонятно, почему предыдущие вызовы считаются равными компиляции, я бы хотел, чтобы компилятор понял, что два указателя неконтекстера относятся к одному и тому же объекту. И они явно не nullptr (потому что они не могут быть - никакой действительный адрес не может быть равен nullptr) http://en.cppreference.com/w/cpp/language/typeid –

+1

@RichardHodges, и все же вы можете 'static_assert' их адреса: http://stackoverflow.com/a/29288244/1870760 –

+0

@ GillBates - это не тот же тест? Это static_asserting, что два адреса двух объектов статического хранения одинаковы. Если они являются одним и тем же объектом, тогда они будут - во время компиляции. –

ответ

2

составителей, кажется, придерживаются [expr.const]/(2.20):

— реляционная (5.9) или равенство (5.10) оператор, где результат не определен;

Возможно, указатели на два таких объекта не обязательно указываются как неравные, но, тем не менее, для меня это ошибка.

+0

Я не понимаю этого ответа. – jotik

+0

@jotik [expr.const]/2 перечисляет условия, при которых выражение не является основным постоянным выражением.Ваш код сравнивает два адреса, где неясно, являются ли они четкими или нет, поэтому применяется цитируемый раздел. – Columbo

+0

Почему это не понятно? Что и где ошибка? – jotik

Смежные вопросы