Reputation: 23
I've a class which takes a reference to an array of size 5 as one of the parameter in the constructor.
class sha1 {
public:
typedef unsigned int(&type)[5];
type digest_;
sha1(const type digest) : digest_(digest)
{}
};
I am able to instantiate this class by passing an array of 5. But replacing that with a call to std::make_tuple fails to compile.
int main(int argc, const char* const argv[]) {
unsigned int digest[5] = { 0 };
const sha1 s(digest);
const sha1 p = std::make_tuple(digest); <-- error here
return 0;
}
Error:
error C2440: 'initializing': cannot convert from 'std::tuple<unsigned int *>' to 'sha1'
note: No constructor could take the source type, or constructor overload resolution was ambiguous
How can I make this work? Code here has been simplified a lot to make it easier to explain. What I am trying to do is to use the class as a key to unordered_map and use emplace to insert entries, which gives the same error.
I am using Visual Studio 2015
Here is the code with unordered_map
#include <iostream>
#include <unordered_map>
class sha1 {
public:
typedef unsigned int(&type)[5];
const type digest_;
const int index_;
sha1(const type digest, int index) : digest_(digest), index_(index)
{}
bool operator==(const sha1& that) const {
return true;
}
};
namespace std {
template<> struct hash<sha1> {
inline size_t operator()(const sha1& p) const {
return 0;
}
};
}
int main(int argc, const char* const argv[]) {
unsigned int digest[5] = { 0 };
const sha1 s(digest, 10); // works
std::unordered_map<sha1, std::string> map;
map.insert(std::make_pair(sha1(digest, 10), "test")); // works
map.emplace(std::piecewise_construct, std::make_tuple(digest, 10), std::make_tuple("test")); // <-- error here
return 0;
}
Upvotes: 2
Views: 455
Reputation: 109289
make_tuple
will decay
the arguments you pass to it before constructing the tuple
, so the unsigned int(&)[5]
type is converted to unsigned int *
, which does not match your sha1
constructor's parameter type.
Use forward_as_tuple
instead to create a tuple of references.
map.emplace(std::piecewise_construct,
std::forward_as_tuple(digest, 10),
std::forward_as_tuple("test"));
Upvotes: 2