- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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; }
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It looks like you must be using the -std=c++14 option in order for std::decay_t to be found.
Anyway this does look a bug and I have entered it into our bug tracking database as DPD200369406.
The problem in our compiler seems to be the reuse of the "scalar" constexpr routine inside the unused member function inside MatrixEvaluator.
So one possible workaround is to create a copy of scalar for use in MatrixEvaluator, i.e. I've created a duplicate routine called
matrixscalar) -- the diff would be:
sptel15-458> diff -c orig.cpp workaround.cpp
*** orig.cpp 2015-04-21 16:27:02.821708000 -0400
--- workaround.cpp 2015-04-21 16:39:57.327377000 -0400
***************
*** 72,82 ****
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 ***********/
--- 72,87 ----
return models<Scalar, T>();
}
+ template <class T>
+ constexpr bool matrixscalar() {
+ return models<Scalar, T>();
+ }
+
/************* Block A ***********/
struct MatrixEvaluator : Concept {
template <class T>
auto require(T&& evaluator)
! -> list<matrixscalar<std::decay_t<decltype(evaluator(0, 0, 0, 0))>>()>;
};
/************* End Block A ***********/
sptel15-459>
Sorry for the inconvenience and thanks for reporting it to us.
Judy
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the response. I found another workaround replacing the decltype expression with std::result_of_t.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page