I'm trying to bind some ta-lib functions and then callback.
Here is the simplified sample code:
#include <functional>
#include <type_traits>
#include <cstdint>
struct DataChunk {
// ...
};
typedef uint64_t idx_t;
template <typename LookbackArgType> // int, double
struct talib_traits {
using talib_lookback_t = std::function<int(LookbackArgType)>;
using talib_function_t = std::function<void(DataChunk &, void *, idx_t, idx_t, LookbackArgType)>;
};
template <>
struct talib_traits<void> {
using talib_lookback_t = std::function<int()>;
using talib_function_t = std::function<void(DataChunk &, void *, idx_t, idx_t)>;
};
struct X {
talib_traits<int>::talib_lookback_t talib_lookback_int = nullptr;
talib_traits<int>::talib_function_t talib_function_int = nullptr;
talib_traits<double>::talib_lookback_t talib_lookback_double = nullptr;
talib_traits<double>::talib_function_t talib_function_double = nullptr;
talib_traits<void>::talib_lookback_t talib_lookback_void = nullptr;
talib_traits<void>::talib_function_t talib_function_void = nullptr;
explicit X(talib_traits<int>::talib_lookback_t talib_lookback, talib_traits<int>::talib_function_t talib_function)
: talib_lookback_int(talib_lookback), talib_function_int(talib_function) {
}
explicit X(talib_traits<double>::talib_lookback_t talib_lookback,
talib_traits<double>::talib_function_t talib_function)
: talib_lookback_double(talib_lookback), talib_function_double(talib_function) {
}
explicit X(talib_traits<void>::talib_lookback_t talib_lookback, talib_traits<void>::talib_function_t talib_function)
: talib_lookback_void(talib_lookback), talib_function_void(talib_function) {
}
};
int main() {
constexpr bool lookback_is_same =
std::is_same<talib_traits<int>::talib_lookback_t, talib_traits<double>::talib_lookback_t>::value;
constexpr bool function_is_same =
std::is_same<talib_traits<int>::talib_function_t, talib_traits<double>::talib_function_t>::value;
static_assert(!lookback_is_same && !function_is_same);
X x([](void) { return 0; }, [](DataChunk &, void *, idx_t, idx_t) {}); // okay
// ambiguous: more than one instance of constructor "X::X" matches the argument list, int or double?
X y([](int) { return 0; }, [](DataChunk &, void *, idx_t, idx_t, int) {});
}
How can I make them unambiguous, that is, something like preventing std::function<int(int)>
/int (*)(int)
from being converted to std::function<int(double)>
?
I tried to prefix explicit
keyword to the constructors, still it doesn't prevent ambiguousness.
-std=c++[11,14,17,20]
, all don't work. – Snappishstd::function
. If I assign the lambda to astd::function
variable, it works. godbolt.org/z/o8so5ncvK – Kendrystd::function
, then almost all conversions are forbidden. I assume that you've ruled out that option because you want stateful lambdas withoutstatic
variables? – Empyema