- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I've stumbled across a problem where icpc fails to correctly interpret a template argument list expansion. In particular, the problem occurs when a struct is templated on a variadic template argument list and that list is then expanded into a non-trivial expression like std::shared_ptr<T>... as part of a method signature.
Here is a small example:
[cpp]
#include <memory>
#include <tuple>
template<typename... T>
struct A
{
A(std::shared_ptr<T>... t)
: _t(t...)
{}
std::tuple<std::shared_ptr<T>...> _t;
};
int main()
{
A<int,double> a(std::make_shared<int>(3),std::make_shared<double>(3.1));
return 0;
}
[/cpp]
Compiling that code works fine on both GCC 4.8.1 and clang 3.4, but fails with ICC (icpc (ICC) 14.0.1 20131008). All compilation was on Linux. The error is:
[plain]
$ icpc -std=c++11 parameterpack.cc
parameterpack.cc(8): error: parameter pack "T" was referenced but not expanded
A(std::shared_ptr<T>... t)
^
parameterpack.cc(8): error: pack expansion does not make use of any argument packs
A(std::shared_ptr<T>... t)
^
parameterpack.cc(18): error: no instance of constructor "A<T...>::A [with T=<int, double>]" matches the argument list
argument types are: (std::shared_ptr<int>, std::shared_ptr<double>)
A<int,double> a(std::make_shared<int>(3),std::make_shared<double>(3.1));
^
compilation aborted for parameterpack.cc (code 2)
[/plain]
If you take out the shared_ptr and just use the plain parameter pack in both the constructor signature and the tuple, ICC manages to compile the code.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Steffan,
I was able to reproduce this bug in 14.0. It has been fixed in our development compiler (which will become our next release).
I have opened a bug report (tracking number DPD200253119) to port this fix back into 14.0 but it's too late to get that into 14.0 update 2 so it will have to wait for update 3.
In the meantime this is a description of the bug:
Spurious error on certain pack expansions in constructor declarations
If a constructor declaration began with a pack expansion where the pack
that was named was not at the top level in the function declarator (e.g.,
in the example below the pack T is not the immediate parameter type but rather
is used inside a template argument list), spurious errors could be issued
about the pack not being expanded and later that the pack expansion did
not make use of any packs. The errors resulted from the failure to handle
packs in the disambiguation of a constructor declaration, so the error
only occurred when the pack was the first parameter of the constructor.
Now fixed.
template <typename T> struct A {};
template <typename... T> struct B {
B(A<T>... ts);
};
and based on the description a possible workaround would be to add a dummy first argument to the constructor, i.e.:
#include <memory>
#include <tuple>
template<typename... T>
struct A
{
#ifdef WORKAROUND
A(int /*dummy*/, std::shared_ptr<T>... t) // workaround for bug
#else
A(std::shared_ptr<T>... t)
#endif
: _t(t...)
{}
std::tuple<std::shared_ptr<T>...> _t;
};
int main()
{
#ifdef WORKAROUND
A<int,double> a(/*dummy=*/0, std::make_shared<int>(3),std::make_shared<double>(3.1));
#else
A<int,double> a(std::make_shared<int>(3),std::make_shared<double>(3.1));
#endif
return 0;
}
Sorry for the trouble that this bug has caused you.
Judy
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Judy,
thanks for checking on the issue! We'll be able to work around the problem until the next feature release.
Steffen

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