Reputation: 67355
I have the following templated function:
template<typename T = CRecordset>
std::unique_ptr<T> ExecuteSqlQuery(LPCTSTR pszSqlQuery = nullptr, RecordsetMode nMode = RecordsetMode::read)
{
ASSERT(m_Database.IsOpen());
std::unique_ptr<ITableRecordset> prs = std::make_unique<T>(&m_Database);
if (!ExecuteSqlQuery(prs.get(), pszSqlQuery, nMode))
prs.reset();
return prs;
}
And I'm calling it like this:
auto prs = db.ExecuteSqlQuery<CCustomerRecordset>(nullptr, RecordsetMode::bulkRead);
CCustomerRecordset
derives from CTableRecordset<>
, and CTableRecordset<>
derives from ITableRecordset
.
However, the return statement in the function gives me an error:
Error C2440 'return': cannot convert from std::unique_ptr<ITableRecordset,std::default_delete<_Ty>>' to 'std::unique_ptr<CCustomerRecordset,std::default_delete<_Ty>>'
with
[
_Ty=ITableRecordset
]
and
[
_Ty=CCustomerRecordset
]
Since CCustomerRecordset
is a type of ITableRecordset
, why can't I do this?
Upvotes: 1
Views: 543
Reputation: 170299
Your example reduces to this:
struct A {};
struct B : A {};
A *a = new B;
B *b = a;
The return statement is trying to return a unique_ptr<ITableRecordset>
where a unique_ptr<CCustomerRecordset>
is expected. It's a downcast, and won't happen implicitly. A way to fix it would be to make full use of the concrete type throughout the function template. So instead of converting to the interface:
auto prs = std::make_unique<T>(&m_Database);
Upvotes: 2