Quantcast
Channel: Intel® C++ Compiler
Viewing all articles
Browse latest Browse all 1616

valid code corrupts compiler and causes bug in template deduction

$
0
0

The following code below works fine in clang or gcc, but fails with intel compiler 2016.

Note if you comment out the section of code labeled block A (which has nothing to do with anything and isn't referenced) the code compiles. It seems that somehow it's corrupting icc. Please suggest a work around and let me know when you have a patch available.

#include <type_traits>

template <bool... Values>
struct And {
  static constexpr bool value = true;
};

template <bool ValueFirst, bool... ValuesRest>
struct And<ValueFirst, ValuesRest...> {
  static constexpr bool value = ValueFirst && And<ValuesRest...>::value;
};

class Concept {
 protected:
  // list
  template <bool... Values>
  using list = std::integral_constant<bool, And<Values...>::value>;

  // valid
  template <class T>
  static constexpr bool valid() {
    return true;
  }

  // same
  template <class A, class B>
  static constexpr bool same() {
    return std::is_same<A, B>();
  }

  // convertible
  template <class A, class B>
  static constexpr bool convertible() {
    return std::is_convertible<A, B>();
  }
};

namespace detail {
namespace concept {

template <
    class Concept, class... Args,
    typename T = decltype(std::declval<Concept>().template require<Args...>(
        std::declval<Args>()...)),
    typename std::enable_if<std::is_same<T, std::true_type>::value, int>::type =
        0>
std::true_type models_(Args&&... args);

template <class Concept, class... Args>
std::false_type models_(...);

}  // end namespace concept
}  // end namespace detail

template <class Concept, class... Args>
constexpr bool models() {
  using Result = decltype(
      detail::concept::models_<Concept, Args...>(std::declval<Args>()...));
  return Result{};
}

struct Scalar : Concept {
  template <class T>
  auto require(T&& x)
      -> list<std::is_pod<T>::value, same<T, decltype(-x)>(),
              same<T, decltype(x + x)>(), same<T, decltype(x - x)>(),
              same<T, decltype(x* x)>(), same<T, decltype(x / x)>()>;
};

template <class T>
constexpr bool scalar() {
  return models<Scalar, T>();
}

/*************   Block A   ***********/
struct MatrixEvaluator : Concept {
  template <class T>
  auto require(T&& evaluator)
      -> list<scalar<std::decay_t<decltype(evaluator(0, 0, 0, 0))>>()>;
};
/************* End Block A ***********/

struct VectorEvaluator : Concept {
  template <class T>
  auto require(T&& evaluator)
      -> list<scalar<std::decay_t<decltype(evaluator(0))>>()>;
};

template <class T>
constexpr bool vector_evaluator() {
  return models<VectorEvaluator, T>();
}

int main() {
  auto f = [](int x) -> double { return x * x; };
  static_assert(vector_evaluator<decltype(f)>(), "");
  return 0;
}

 

 


Viewing all articles
Browse latest Browse all 1616

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>