2014-11-04 3 views
1

Я пытаюсь запретить ссылки на класс, который у меня есть, и я вижу странное поведение. Я построил игрушечный пример, который показывает, что происходит. Если у меня есть это:Требуется ли static_assert использовать параметр шаблона?

template <class T> 
struct something { 
}; 

template <class T> 
struct something<T&> { 
    static_assert(false, "reference disallowed with something"); 
}; 


int main() { 
    something<int> a; (void)a; 
} 

Даже если я не объявляя экземпляр чего-то со ссылкой, он до сих пор не удается:

> g++ -std=c++11 foo.cc -o foo 
foo.cc:7:5: error: static assertion failed: reference disallowed with something 
    static_assert(false, "reference disallowed with something"); 
    ^

Если я настроить его так, что он должен использовать шаблон параметр через прокси-класс, то он работает:

template <class T> 
struct something { 
}; 

template <class T> 
struct something<T&> { 
    template <class TT> struct falsity { 
     static const bool value = false; 
    }; 
    static_assert(falsity<T>::value, "reference disallowed with something"); 
}; 

int main() { 
    something<int> a; (void)a; 
} 

Тогда это работает просто отлично, это ожидаемое поведение? Я бы подумал, что static assert будет членом класса независимо.

Edit: это GCC версии 4.8.2 (Ubuntu 4.8.2-19ubuntu1)

+0

Короче: Нет! Попробуйте 'static_assert (false,« Это false ».);' –

+0

@ πάντα ῥεῖ: Я не уверен, что понимаю, вы не думаете, что это ожидаемое поведение? Где я должен попытаться утверждать? –

+0

_ «Где я должен попытаться утверждать?» _ В другом месте. Точка: ** Это не требует использования параметров шаблона. ** –

ответ

3

static_assert Ваш не зависит от каких-либо параметров шаблона и поэтому компилятор не придется ждать, пока конкретизации шаблона класса к оценить утверждение. Вместо этого он делает это во время первой фазы two phase name lookup, и ваш код не скомпилируется.

В вашем случае вы можете исправить сбой, изменив утверждение к

static_assert(!std::is_lvalue_reference<T>::value, "reference disallowed with something"); 
+0

Ah OK имеет смысл, звучит так, как ответ: _yes_ вам нужно использовать параметр шаблона, или вы будете в принципе бросать утверждение независимо от того, чтобы создать экземпляр класса. –

+0

@gct Правильно, сделав условие зависимым на параметре шаблона компилятор должен дождаться момента создания шаблона для вычисления выражения. – Praetorian

+1

Мне потребовалось некоторое время, чтобы выкопать e цитата из стандарта: 14.6/8 * Если для определения шаблона не может быть создана действительная специализация, и этот шаблон не создается, определение шаблона плохо сформировано, не требуется диагностика. * Это относится к вопросу, поскольку 'static_assert' не зависит от аргументов шаблона, не может быть никакой * действительной специализации *, сгенерированной из этого определения. –

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