Это вопрос до Detecting constexpr with SFINAE.SFINAE constexpr with std :: get
Я хочу определить, является ли элемент кортежа (или что-нибудь, что можно использовать с std::get
) является constexpr. Поэтому я написал следующие похожие на то, что дало Xeo помощникам:
template<size_t> struct sfinae_true : std::true_type{};
template<size_t N, class T>
auto check(const T& arg) -> sfinae_true<(std::get<N>(arg),N)>;
template<size_t N, class>
std::false_type check(...);
Теперь мой тестовый код драйвера:
int main()
{
constexpr std::tuple<size_t, size_t> arg(4,5);
typedef decltype(check<0,decltype(arg)>(arg)) is_cexpr;
std::cout << "is constexpr? " << is_cexpr::value << '\n';
}
Однако, это всегда печатает false
для меня! Для того, чтобы проверить, что по какой-то причине ложной перегрузки не всегда будет вызван, я закомментирована ложной перегрузки и получите ошибку компиляции:
note: candidate template ignored: substitution failure [with N = 0, T = const std ::tuple]: non-type template argument is not a constant expression
auto check(const T& arg) -> sfinae_true<(std::get(arg),0)>;
Однако, я знаю, что я могу назвать std::get<N>(arg)
и получить значение constexpr :
template<size_t N>
class A{};
int main()
{
constexpr std::tuple<size_t, size_t> arg(4,5);
A<std::get<0>(arg)> a_val;
}
Это компилируется просто отлично.
- Почему функция проверки не обнаруживает constexprness правильно?
- Как исправить это?
Я тестировал это с помощью Clang 3.8.0 на Ubuntu 16.04.
редактировать:
В качестве дополнительного теста на основе ответа Сэма, я попробовал форму:
template<size_t N, class T>
auto check(const T& arg)
{
return sfinae_true<(std::get<N>(arg)*0)>();
}
Это избавляется от оператора запятая полностью, что GCC 5.4.0 компилирует просто отлично , но Clang 3.8.0 все еще жалуется. Интересно, что Кланг подчеркивает, что arg
сам не является constexpr.
Почему эта проблема еще не решена? Каковы правила для аргументов функции constexpr?
Проблема заключается в том, что параметр 'arg' не является' constexpr' ... – Jarod42
(Чтобы немного расширить то, что я думаю @ Jarod42 означает: 'arg' является параметром функции никогда не рассматривается как постоянное выражение, даже если аргумент, который вы предоставляете функции, является постоянным выражением.) – dyp
Как бы определить, будет ли результат вызова функции constexpr, если этот метод не работает? Ясно, что я могу использовать кортеж как значение constexpr, создав объект 'a_val'. – helloworld922