I want to pass a lambda to a function, but I have run into a problem of successfully passing it onto the function. The function chooses to append TrueVal or FalseVal and creates a vector of boolean, based on the given condition.
I'm using 2019 Visual Studio's ISO C++14 Standard to compile the code.
#include <iostream>
#include <vector>
using namespace std;
template<typename T, typename T1, typename T2>
vector<bool> ConstructNestedVectorByElements(T condition, T1 TrueVal, T2 FalseVal) {
vector<bool> TempCol;
TempCol = {};
for (int i = 0; i < 3; i++)
{
if (condition(i)) {
TempCol.emplace_back(TrueVal);
}
else {
TempCol.emplace_back(FalseVal);
}
}
return TempCol;
}
int main()
{
vector<int> NumList = { 0, 1, 2 };
vector<bool> BoolList = {true, false, true};
auto ElementIsZero = [&NumList](int i) {return NumList[i] == 0; };
vector<bool> a = ConstructNestedVectorByElements(ElementIsZero, true, false); //this works
auto OriginalElement = [&BoolList](int i) {return BoolList[i]; };
vector<bool> b = ConstructNestedVectorByElements(ElementIsZero, true, OriginalElement); //error
return 0;
};
The error message:
C2440 'initializing': cannot convert from 'T2' to 'bool' ...\include\vector line 2385
1>...\vector(2385,18): error C2440: 'initializing': cannot convert from 'T2' to 'bool'
1> with
1> [
1> T2=main::<lambda_e116e485fb739b952327b9205614af81>
1> ]
1>...\vector(2385,18): message : No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>...\Source.cpp(19): message : see reference to function template instantiation 'decltype(auto) std::vector<bool,std::allocator<bool>>::emplace_back<T2&>(T2 &)' being compiled
1> with
1> [
1> T2=main::<lambda_e116e485fb739b952327b9205614af81>
1> ]
1>...\Source.cpp(36): message : see reference to function template instantiation 'std::vector<std::vector<bool,std::allocator<bool>>,std::allocator<std::vector<bool,std::allocator<bool>>>> ConstructNestedVectorByElements<main::<lambda_52b07f243bfcbbd5a342ddead4700eca>,bool,main::<lambda_e116e485fb739b952327b9205614af81>>(T,T1,T2)' being compiled
1> with
1> [
1> T=main::<lambda_52b07f243bfcbbd5a342ddead4700eca>,
1> T1=bool,
1> T2=main::<lambda_e116e485fb739b952327b9205614af81>
1> ]
template <class... _Valty>
decltype(auto) emplace_back(_Valty&&... _Val) {
bool _Tmp(_STD forward<_Valty>(_Val)...);
push_back(_Tmp);
I think the problem might be one of the following:
- I'm passing more than one type of argument into
T2(a lambda and a bool): Perhaps I used the wrong keyword,typename, to initializeT2? I tried withclassbut the same thing occurred. OriginalElementisn't given parameters when it requires them: This confuses me a bit. If I change the line to:
TempCol.emplace_back(FalseVal(i, j)); //this is line 19
This error shows up:
C2064 term does not evaluate to a function taking 2 arguments ...\Source.cpp line 19
However, this seems not to be the case for condition(i, j), which compiles correctly. Is there a difference in handling (what I assume to be) boolean when in a conditional, and when appending it to a vector?
T2 == booland in the otherT2 == lambda(x). But in both cases you try to push that value to avector<bool>..emplace_back(.., .., ..)instead of..you pass some values that are used as the respective arguments of some constructor of yourvector's type. In your case compiler tries to construct abool(because that's type of element ofTempCol), and as an argument of constructor your pass a lambda object. There's no such constructor ofbool