xerion xerion - 2 months ago 19
C++ Question

Auto deduction for templates

I had a question yesterday in stackoverflow on achieving specific conversions between different template types.

This is the class that was almost proposed. I say almost because I changed small parts of it in hope of simplifying it.

#include <iostream>
#include <type_traits>
// Helper class

template<bool from, bool to>
struct ok_to_copy_foos : std::false_type {};

// Define all valid conversions as specializations:

template<>
struct ok_to_copy_foos<false, false> : std::true_type {};

template<>
struct ok_to_copy_foos<true, false> : std::true_type {};

////////////////////////////////////////////////////////////////////

template<bool Owner>
class Foo {

static constexpr bool owner_ = Owner;

public:

Foo() {}

Foo(const Foo &o)
{
static_assert(ok_to_copy_foos<Owner, Owner>::value, "can only copy from Foo<true> to Foo<false>");
}

Foo& operator=(const Foo& foo)
{
static_assert(ok_to_copy_foos<Owner, Owner>::value, "can only assign from Foo<true> to Foo<false>");
return *this;
}

template<bool U>
Foo(const Foo<U> &)
{
static_assert(ok_to_copy_foos<Owner, Owner>::value, "can only copy from Foo<true> to Foo<false>");
}

template<bool U>
Foo &operator=(const Foo<U> &)
{
static_assert(ok_to_copy_foos<Owner, Owner>::value, "can only assign from Foo<true> to Foo<false>");
return *this;
}

void bar()
{
std::cout << owner_ << " \n";
}
};


In this class the intent is that you can copy or assign but the result should always be a
Foo<false>
while everything else is prohibited. Essentially that means that you cannot copy or assign from
Foo<true>
to Foo`. I am not sure if there is any better way to achieve that but this is what I got at the moment.

However, there is something that will not work as I would like and I wanted some help in achieving that.

Foo<true> t;
auto f = t;


This will lead in compiler error so the question is can the compiler figure out that auto should actually be
Foo<false>
?

Answer

The short answer is: no. C++ simply does not work this way.

auto means: the object being declared is the same type as the expression that initializes it. If this results in a compilation error, the compiler isn't going to try every class it knows about, as an alternative, to see if maybe there's an available conversion that can be used to initialize it from the expression.

Comments