Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

Problem with std::ref and std::vector

Pablo_K_
Beginner
853 Views

Hi guys.

I am using icpc version 16.0.0 (gcc version 5.0.0 compatibility), there seems to be an issue using std::ref and std::vector, i am trying to initalize a bunch of threads with reference for std::vector with the code:

void doTheMath(const int startIndex, const int endIndex, std::vector<int>& matrix, const int givenSeed)
{
	int seed = 0;

	for (int i = startIndex; i < endIndex; ++i) {

		seed = givenSeed + i;
		seed = VAL_A * seed + VAL_B;
		matrix = seed % 100;

	}
}

void Cpp11::randmat(int nrows, int ncols, int s) {

	int totalMatrixSize = nrows * ncols;
	int numThreads = 4;
	int operationsByThread = totalMatrixSize / numThreads;

	std::vector<int> matrix(totalMatrixSize);
	std::vector<std::thread> threadsList;

	for (int i = 0; i < numThreads; ++i) {
		threadsList.emplace_back(std::thread(doTheMath, operationsByThread * i, operationsByThread * (i + 1), std::ref(matrix), s));

	}

	for ( auto &t : threadsList ) {

		t.join();

	}
}

To compile i'm using:

icpc cpp11.cpp randmat.cpp -std=c++11 -pthread

And i'm getting this error:

/usr/include/c++/5/functional(78): error: class "std::vector<int, std::allocator<int>>" has no member "result_type"
      { typedef typename _Functor::result_type result_type; };
                                   ^
          detected during:
            instantiation of class "std::_Maybe_get_result_type<_Functor, void> [with _Functor=std::vector<int, std::allocator<int>>]" at line 86
            instantiation of class "std::_Weak_result_type_impl<_Functor> [with _Functor=std::vector<int, std::allocator<int>>]" at line 184
            instantiation of class "std::_Weak_result_type<_Functor> [with _Functor=std::vector<int, std::allocator<int>>]" at line 264
            instantiation of class "std::_Reference_wrapper_base_impl<true, true, _Tp> [with _Tp=std::vector<int, std::allocator<int>>]" at line 283
            instantiation of class "std::_Reference_wrapper_base<_Tp> [with _Tp=std::vector<int, std::allocator<int>>]" at line 399
            instantiation of class "std::reference_wrapper<_Tp> [with _Tp=std::vector<int, std::allocator<int>>]" at line 36 of "randmat.cpp"

/usr/include/c++/5/functional(266): error: class "std::vector<int, std::allocator<int>>" has no member "argument_type"
        typedef typename _Tp::argument_type argument_type;
                              ^
          detected during:
            instantiation of class "std::_Reference_wrapper_base_impl<true, true, _Tp> [with _Tp=std::vector<int, std::allocator<int>>]" at line 283
            instantiation of class "std::_Reference_wrapper_base<_Tp> [with _Tp=std::vector<int, std::allocator<int>>]" at line 399
            instantiation of class "std::reference_wrapper<_Tp> [with _Tp=std::vector<int, std::allocator<int>>]" at line 36 of "randmat.cpp"

/usr/include/c++/5/functional(267): error: class "std::vector<int, std::allocator<int>>" has no member "first_argument_type"
        typedef typename _Tp::first_argument_type first_argument_type;
                              ^
          detected during:
            instantiation of class "std::_Reference_wrapper_base_impl<true, true, _Tp> [with _Tp=std::vector<int, std::allocator<int>>]" at line 283
            instantiation of class "std::_Reference_wrapper_base<_Tp> [with _Tp=std::vector<int, std::allocator<int>>]" at line 399
            instantiation of class "std::reference_wrapper<_Tp> [with _Tp=std::vector<int, std::allocator<int>>]" at line 36 of "randmat.cpp"

/usr/include/c++/5/functional(268): error: class "std::vector<int, std::allocator<int>>" has no member "second_argument_type"
        typedef typename _Tp::second_argument_type second_argument_type;
                              ^
          detected during:
            instantiation of class "std::_Reference_wrapper_base_impl<true, true, _Tp> [with _Tp=std::vector<int, std::allocator<int>>]" at line 283
            instantiation of class "std::_Reference_wrapper_base<_Tp> [with _Tp=std::vector<int, std::allocator<int>>]" at line 399
            instantiation of class "std::reference_wrapper<_Tp> [with _Tp=std::vector<int, std::allocator<int>>]" at line 36 of "randmat.cpp"

I atached the source and the preprocessor file.

Strangely in g++ there is no problem. Someone can help me? Thanks in advance!

0 Kudos
11 Replies
Kittur_G_Intel
Employee
853 Views

Hi,
Can you compile with -P to generate the preprocessed .i file and attach to this issue? Thx.
_Kittur

0 Kudos
Pablo_K_
Beginner
853 Views

Yes.

0 Kudos
Kittur_G_Intel
Employee
853 Views

Pablo, yes this looks like a bug and I'll file with the developers. BTW, can you can you also attach the source files as well? Thanks.

_Kittur 

0 Kudos
Pablo_K_
Beginner
853 Views

I attached both files in my first post. Keep me advised if possible and thanks for the help.

0 Kudos
Kittur_G_Intel
Employee
852 Views

Great,  thanks Pablo I'll get back to you.

_Kittur

0 Kudos
Kittur_G_Intel
Employee
852 Views

Hi Pablo,
Done with investigation and this is a bug in the compiler for now and is being worked on for a fix. I'll keep you updated as soon as the release with the fix is out.  The bug is due to the recent versions of the GNU headers which use a new c++11 rule (related to SFINAE) to make the right call be chosen and a fix is being implemented.

There's no general workaround for this problem (beyond using a version of GNU older than 5.0) and so you'll have to wait for the compiler release with the fix and I'll keep you updated accordingly when it's out.

For this particular code example you attached, you can add the declaration below, somewhere before the definition of Cpp11::randmat() in your test case: (See attached newrandmat.cpp file with this code change):

namespace std {
   template<typename T>
   struct _Reference_wrapper_base<std::vector<T>> {};
}

Again, appreciate your patience and I'll keep you updated as soon as the release with the fix is out, thanks

_Kittur

 

 

0 Kudos
Shlomi_S_
Beginner
852 Views

Hello,

I am suffering from the same issue. Running latest ICC:
icpc (ICC) 16.0.1 20151021
gcc (SUSE Linux) 5.3.1 20151207 [gcc-5-branch revision 231355]

I get the same error messages, e.g.:
/usr/include/c++/5/functional(78): error: class "lambda []()->std::unique_ptr<Object, std::default_delete<Object>>" has no member "result_type"

I'd like to inquire about fix release date and possible temporary workaround.

Thank you

0 Kudos
Kittur_G_Intel
Employee
852 Views

Hi Shlomi,
As mentioned in my earlier response, there's no general workaround for this problem (beyond using a version of GNU older than 5.0) and so you'll have to wait for the compiler release with the fix and I'll keep you updated accordingly when it's out. Appreciate your patience till then.

Regards,
Kittur

0 Kudos
Shlomi_S_
Beginner
852 Views

Hello,
The fixed in update 2, which I just installed. Happy coincidence.

Thank you
 

0 Kudos
Kittur_G_Intel
Employee
852 Views

Yes, you're correct! Thanks for the confirmation :-)

0 Kudos
Kittur_G_Intel
Employee
852 Views

@Pablo - this is fixed in the latest update 2 release that's out, thanks. As always, appreciate your patience through this...

_Kittur

0 Kudos
Reply