К вашему сведению, сбой во время компиляции обычно мешает компиляции ... вот почему они все-таки здесь.
Я могу придумать два способа сделать то, что вы предлагаете:
- с использованием SFINAE
- с использованием специальных параметров компилятора
SFINAE
Буквально, SFINAE означает: Ошибка замещения естьНе ошибка .Он применяется к контексту шаблона и позволяет тихо отбрасывать функции, которые оказываются неадекватными, из набора перегрузки.Использование SFINAE привело к идее проверки концепции и категоризации свойств с использованием признаков, которые используются для поддержки этих проверок.
В вашем случае это означает, что если вы можете каким-то образом поместить желаемое выражениечтобы протестировать в контексте, в котором может применяться SFINAE, вы можете попытаться обнаружить, что конкретная функция была фактически отброшена.
Например:
#include <iostream>
#include <utility>
struct Foo {};
struct Bar {};
template <typename T>
auto foo(T t) -> decltype(std::declval<Foo>() + t) { std::cout << "T\n"; }
void foo(...) { std::cout << "ellipsis\n"; }
int main() { foo(Bar()); }
выход:
ellipsis
(см. ideone ), хотя нигде не определено operator+(Foo, Bar)
.
К сожалению, это может работать не во всех случаях (пока не ясно), но оно должно быть переносимымна всех совместимых компиляторах.
Специфично для компилятора
Другая возможность состоит в использовании специфических функций компилятора.Наборы тестов компилятора должны убедиться, что эти компиляторы правильно диагностируют ошибки, и в вашем случае выдают ошибку при выполнении условия static_assert
.Поэтому у компиляторов, вероятно, есть зацепки для этого.
Например, в наборе тестов Clang можно найти файл SemaCXX/static-assert.cpp
:
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
int f();
static_assert(f(), "f"); // expected-error {{static_assert expression is not an integral constant expression}}
static_assert(true, "true is not false");
static_assert(false, "false is false"); // expected-error {{static_assert failed "false is false"}}
void g() {
static_assert(false, "false is false"); // expected-error {{static_assert failed "false is false"}}
}
class C {
static_assert(false, "false is false"); // expected-error {{static_assert failed "false is false"}}
};
template<int N> struct T {
static_assert(N == 2, "N is not 2!"); // expected-error {{static_assert failed "N is not 2!"}}
};
T<1> t1; // expected-note {{in instantiation of template class 'T<1>' requested here}}
T<2> t2;
template<typename T> struct S {
static_assert(sizeof(T) > sizeof(char), "Type not big enough!"); // expected-error {{static_assert failed "Type not big enough!"}}
};
S<char> s1; // expected-note {{in instantiation of template class 'S<char>' requested here}}
S<int> s2;
-fsyntax-only
избежать генерации кода и -verify
означает, что компилятор проверяет, что указанные expected-note
, expected-warning
и expected-error
правильно выполнены.
Если это не так, компилятор вернется с кодом ошибки.Конечно, это, вероятно, зависит от компилятора.