- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The following example code doesn't compile with icc 14.0.2 in C++11 mode, although it seems to be standard compliant code (and both g++ 4.8.1 and clang++ compile it without complaint).
This may or may not be related to https://software.intel.com/en-us/forums/topic/500790 / DPD200252873, but I couldn't really figure out what causes the problems. It might be a name-lookup issue with helper templates being lookup up in the wrong namespaces, or the variadic templates in general. I couldn't really narrow it down any further...
The first version in main.cpp that directly calls the internal function from the THDetail-namespace seems to work, the public one in TH:: which does exactly the same thing is not found or otherwise causes unhappiness.
/* > icc -v icc version 14.0.2 (gcc version 4.8.0 compatibility) > icc --std=c++11 yet_another_icc_bug.cpp yet_another_icc_bug.cpp(53): error: no instance of function template "TH::GetEveryNthElement" matches the argument list argument types are: (std::tuple<int, double, float>) auto t0 = TH::GetEveryNthElement<1u, 0u>(t2); // no work ^ compilation aborted for yet_another_icc_bug.cpp (code 2) Same code compiles fine with g++ or clang++. May (or not) be related to https://software.intel.com/en-us/forums/topic/500790 / DPD200252873. */ #include <tuple> #include <type_traits> #include <utility> namespace TH { template<unsigned ...Is> struct Indices { }; template<unsigned N, unsigned ...Is> struct BuildIndices : BuildIndices<N-1, N-1, Is...> { }; template<unsigned ...Is> struct BuildIndices<0, Is...> : Indices<Is...> { }; template<typename T> using Value = typename std::remove_cv<typename std::remove_reference<T>::type>::type; template<typename Tuple> using IndicesForTuple = BuildIndices<std::tuple_size<Value<Tuple> >::value>; namespace THDetail { template<unsigned N, unsigned Offset, typename Tuple, unsigned ...Is> inline auto GetEveryNthElementImpl(Tuple &&t, Indices<Is ...>) -> decltype(std::tuple<typename std::tuple_element<Offset + N * Is, Value<Tuple> >::type ...>( std::get<Offset + N * Is>(std::forward<Tuple>(t)) ...)) { static_assert(N >= 1u, "Index-multiplier smaller than 1!"); return std::tuple<typename std::tuple_element<Offset + N * Is, Value<Tuple> >::type ...>( std::get<Offset + N * Is>(std::forward<Tuple>(t)) ...); } } // end namespace THDetail template<unsigned N, unsigned Offset = 0u, typename Tuple> inline auto GetEveryNthElement(Tuple &&t) -> decltype(THDetail::GetEveryNthElementImpl<N, Offset>(std::forward<Tuple>(t), BuildIndices<(std::tuple_size<Value<Tuple> >::value - Offset + N - 1u) / N>())) { static_assert(Offset < N, "Offset is larger than index-multiplier!"); return THDetail::GetEveryNthElementImpl<N, Offset>(std::forward<Tuple>(t), BuildIndices<(std::tuple_size<Value<Tuple> >::value - Offset + (N - 1u)) / N>()); } template<unsigned N, unsigned Offset, typename Tuple> using TupleEveryNthElement = decltype(GetEveryNthElement<N, Offset, Tuple>(std::declval<Tuple>())); } // end namespace TH int main(int argc, char const *argv[]) { std::tuple<int, double, float> t2; auto tm1 = TH::THDetail::GetEveryNthElementImpl<1u, 0u>(t2, TH::BuildIndices<(std::tuple_size<decltype(t2)>::value - 0u + (1u - 1u)) / 1>()); // works auto t0 = TH::GetEveryNthElement<1u, 0u>(t2); // no work return 0; }
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
icc 15.0.0 Beta Update 2 is also affected.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is not related to cq #252873 which was a bug having to do with variadic template argument deduction and has been fixed since March 2014.
A small example of the problem you are seeing is below. As you can see, the problem seems to be the explicit template arguments used in the late specified return type.
I have submitted this bug as DPD200358811 in our internal bugs database. Thank you for reporting it.
template<typename N, typename Tuple>
#ifdef OK
int fooImpl(N,Tuple);
#else
int fooImpl(Tuple);
#endif
template<typename Tuple>
auto foo(Tuple t)
#ifdef OK
-> decltype(fooImpl(3,t));
#else
-> decltype(fooImpl<int>(t));
#endif
int main()
{
foo(4);
return 0;
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Judith.
I'm not sure if this is relevant here, but as they template arguments in my case are not types but PODs (unsigned in this case) I unfortunately cannot let the compiler deduce them and need to specify them explicitly.
I'd made my own bug report (as I did register a premium account for the XE 2015 beta) as 6000058730 if that helps.
As mentioned in the bug report, I have a set of unit tests for the file the above code was reduced from, which could help fix more bugs faster if you're interested. They fail to compile in many, many places with icc.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hmmmm. If in line 53 and 57 in my example I explicitly specify Tuple as last template argument to the implementation function (instead of letting the compiler re-deduce it), it seems to compile....
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes Daniel your original example uses a non-type template argument instead of a template argument but I think it's the same underlying problem. I realize this bug may not be easy to workaround in your case, sorry about that.
If you have other test cases that you think are showing different compiler bugs please file them as separate bugs (either through Premier or here). That would be much appreciated! We can always close them as duplicates if we figure out they are the same. I know sometimes it's really hard to tell.
thanks,
Judy
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've updated my bug report 6000058730 with a self-contained unit-test for our TemplateHelper.hpp header that triggers many more of these C++11 template issues.

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