Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Привет всем.
Тут одна мысль посетила, благодаря
rg45Автор: rg45
Дата: 26.09.19
. Но я решил с ней повременить.
| И привести нормальный пример описываемой проблемы (VS2019) |
| ////////////////////////////////////////////////////////////////////////////////
#include <iostream>
////////////////////////////////////////////////////////////////////////////////
//class t_errors
class t_errors
{
public:
virtual void add(int errCode)=0;
};
////////////////////////////////////////////////////////////////////////////////
//class t_context
class t_context
{
private:
t_context(const t_context&)=delete;
t_context& operator = (const t_context&)=delete;
public:
class tag_errs_without_limits:public t_errors
{
public:
explicit tag_errs_without_limits(t_context* const pCtx):m_pCtx(pCtx){;}
virtual void add(int errCode)override {m_pCtx->helper__add_error(errCode);}
private:
t_context* m_pCtx;
};//class tag_errs_without_limits
public:
class tag_errs_with_limits:public t_errors
{
public:
explicit tag_errs_with_limits(t_context* const pCtx):m_pCtx(pCtx){;}
virtual void add(int errCode)override {/*check limits*/; m_pCtx->helper__add_error(errCode);}
private:
t_context* m_pCtx;
};//class tag_errs_with_limits
public:
t_context()
{}
tag_errs_without_limits get_errors_without_limits()
{
return tag_errs_without_limits(this);
}//get_errors_without_limits
tag_errs_with_limits get_errors_with_limits()
{
return tag_errs_with_limits(this);
}//get_errors_with_limits
private:
void helper__add_error(int const errCode)
{
std::cout<<"helper__add_error: "<<errCode<<"!\n";
}
};
////////////////////////////////////////////////////////////////////////////////
//add_error - может быть виртуальным методом некоторого класса
void add_error(t_errors& errs,int const errCode)
{
errs.add(errCode);
}//add_error
////////////////////////////////////////////////////////////////////////////////
int main()
{
t_context ctx;
add_error(ctx.get_errors_without_limits(),1);
add_error(ctx.get_errors_with_limits(),2);
return 0;
}//main
////////////////////////////////////////////////////////////////////////////////
|
| |
| Как это сейчас модно говорить, Real World Code (RWC) выглядит так: |
| //...
virtual void GetData_AddErrorRecord__CantGetData
(typename call_ctx_type::errors_type& Errors,
const TBaseColumnsInfoImpl* pColumnsInfo,
const DBBINDING& Binding,
const void* pData,
HRESULT get_data_hr)=0;
//...
template<class TStorageTraits>
HRESULT TMemRowsetStorageROImpl<TStorageTraits>::GetData
(call_ctx_type& CallCtx,
TRowBmk const Bmk,
const TBindingArray* const pBindingArray,
const TBaseColumnsInfoImpl* const pColumnsInfo,
void* const pData)
{
//....
if(get_data_hr!=S_OK)
{
this->GetData_AddErrorRecord__CantGetData
(CallCtx.ErrorsWithLimit(), //<---------------- Вот проблемная точка
pColumnsInfo,
*pBinding,
pData,
get_data_hr); //no throw
++cntErrors;
}//if
//....
}//GetData
//...
|
| |
Когда Conformance Mode=Yes, пример не компилируется:
Error C2664 'void add_error(t_errors &,const int)': cannot convert argument 1 from 't_context::tag_errs_without_limits' to 't_errors &'
Error C2664 'void add_error(t_errors &,const int)': cannot convert argument 1 from 't_context::tag_errs_with_limits' to 't_errors &'
Как я тут уже
отмечалАвтор: Коваленко Дмитрий
Дата: 26.09.19
, ошибку компиляции можно задавить с помощью *&. Но вылезут предупреждения 4-го уровня:
add_error(*&ctx.get_errors_without_limits(),1); //warning C4238: nonstandard extension used: class rvalue used as lvalue
add_error(*&ctx.get_errors_with_limits(),2); //warning C4238: nonstandard extension used: class rvalue used as lvalue
Можно переделать add_error, чтобы он получал указатель на errs. Тоже компилируется с предупреждениями 4-го уровня:
void add_error(t_errors* errs,int const errCode);
//...
add_error(&ctx.get_errors_without_limits(),1); //warning C4238: nonstandard extension used: class rvalue used as lvalue
add_error(&ctx.get_errors_with_limits(),2); //warning C4238: nonstandard extension used: class rvalue used as lvalue
//...
Как по мне, начальный вариант со ссылкой выглядел лучше.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --