In a c++11
project I have some structs like those:
#include <type_traits>
template <bool B, class T = void> using disable_if_t = typename std::enable_if<!(B), T>::type;
enum class disable {};
template <int A> struct StructA
{
using sa = StructA<A>;
static constexpr int a = A;
static constexpr int b = 1;
};
template <typename SA, int B> struct StructB
{
using sa = typename SA::sa;
static constexpr int a = sa::a;
static constexpr int b = B;
};
template <typename SB, typename = int> struct disable_first : std::integral_constant<bool, SB::a == 0 && SB::b == 1>
{
};
template <typename> struct disable_second : std::false_type
{
};
template <typename, typename> class StructC;
template <typename SB, typename T2> struct disable_second<StructC<SB, T2>> : std::true_type
{
};
template <typename SB, typename T> struct StructC
{
template <typename T2, disable_if_t<disable_first<SB, T2>{} || disable_second<T2>{}, disable>...> explicit StructC(T2 v) noexcept;
template <typename SB2, typename T2> StructC(const StructC<SB2, T2>& v) noexcept;
template <typename SB2, typename T2> StructC(StructC<SB2, T2>&& v) noexcept;
};
template <typename T, typename T2> void Func(StructC<StructA<1>, T2> b);
int main()
{
StructC<StructB<StructA<1>, 1>, int> x(40);
Func<float>(x);
return 0;
}
Now I basically have two quesions:
Can the
StructC(const StructC<SB2, T2>& s)
constructor used as copy-constructor (same counts forStructC(StructC<SB2, T2>&& s)
for move constructing)How can I say the compiler, that it's totally OK to call
Func
withStructB<StructA<1>, 1>
andint
although it requiresStructA<1>
andfloat
without explicitly calling the constructor? The constructor ofStructC
is totally capable of converting between those.
Edit 1: provide an example which fails correctly.