In the below code, the compiler can't figure out which constructor I want to use. Why, and how do I fix this? (Live example)
#include <tuple>
#include <functional>
#include <iostream>
template<typename data_type, typename eval_type, typename Type1, typename Type2>
class A
{
public:
using a_type = std::tuple<Type1, Type2>;
using b_type = std::tuple<std::size_t,std::size_t>;
inline explicit constexpr A(const std::function<data_type(a_type)>& Initializer,
const std::function<eval_type(data_type)>& Evaluator,
const Type1& elem1, const Type2& elem2)
{
std::cout << "idx_type" << std::endl;
}
inline explicit constexpr A(const std::function<data_type(b_type)>& Initializer,
const std::function<eval_type(data_type)>& Evaluator,
const Type1& elem1, const Type2& elem2)
{
std::cout << "point_type" << std::endl;
}
};
int main()
{
int a = 1;
long long b = 2;
auto c = A<double, double, long long, int>{
[](std::tuple<long long,int> p)->double { return 1.0*std::get<0>(p) / std::get<1>(p); },
[](double d)->double { return d; }, b,a
};
return 0;
}
std::function
. – Letoa_type
andb_type
are different. – Magentastd::function
. – Magentastd::tuple<long long,int>
andstd::tuple<std::sizt_t,int>
are constructible from each other. – Letob_type
– Reciprocityexplicit
should prevent the conversion fromstd::tuple<long long,int>
tostd::tuple<long long,int>
– Reciprocityusing b_type = struct { std::size_t a; std::size_t b; };
– Disparitystd::tuple<long long,int>
tostd::tuple<long long,int>
" It does if you change that converting constructor to a one argument constructor callable only by direct initialization, by marking itexplicit
, or if you remove that implicit conversion operator, whichever it is that perform the conversion (I haven't checked and don't want to, as it's irrelevant for the point I'm making). But then of coursestd::tuple
is not a customization point, you can't change it. – Provo