简体   繁体   中英

Default template type gives error but explicit type does not

My CCustomerBulkRecordset class is declared something like this:

template <class T = CRecordsetEx>
class CCustomerBulkRecordset : public T
{
    // Member declarations
};

And I have a method in my CRemoteDatabase class that looks like this:

template<typename T = CRecordset>
std::unique_ptr<T> ExecuteSqlQuery(LPCTSTR pszSqlQuery, UINT nOpenType = AFX_DB_USE_DEFAULT_TYPE, DWORD dwOptions = CRecordset::none)
{
    // ...
}

I can use the following code to to call that method and it works fine.

CRemoteDatabase db;
db.Open();
auto prs = db.ExecuteSqlQuery<CCustomerBulkRecordset<CRecordset>>(NULL, CRecordset::forwardOnly, CRecordset::useMultiRowFetch);

But the following code gives me a compile errors.

CRemoteDatabase db;
db.Open();
auto prs = db.ExecuteSqlQuery<CCustomerBulkRecordset>(NULL, CRecordset::forwardOnly, CRecordset::useMultiRowFetch);

Error C2672 'CDatabaseCommon::ExecuteSqlQuery': no matching overloaded function found

Error C3206 'CDatabaseCommon::ExecuteSqlQuery': invalid template argument for 'T', missing template argument list on class template 'CCustomerBulkRecordset'

The only difference is that I'm not specifying the CCustomerBulkRecordset type name in the second one. But since it defaults to CRecordset , shouldn't the two versions work the same?

In

template<typename T = CRecordset>
std::unique_ptr<T> ExecuteSqlQuery(...)

T is a template parameter. That means it must be deduced to a single type, or provided a type explicitly. When you do

auto prs = db.ExecuteSqlQuery<CCustomerBulkRecordset<CRecordset>>(...);

You give it the type CCustomerBulkRecordset<CRecordset> . When you do

auto prs = db.ExecuteSqlQuery<CCustomerBulkRecordset>(...);

You are giving it CCustomerBulkRecordset , which is not a type, but instead it is a template. In order to pass a template to a function you need to use a template template parameter .

The presence of the default template parameter does not turn CCustomerBulkRecordset into CCustomerBulkRecordset<CRecordset> . In order to get that you need CCustomerBulkRecordset<> as the <> indicates you want to instantiate the template with the default value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM