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; }