Моя идея состояла в функция, которая на самом деле делает преобразование; Эта свободная функция будет определена только для типов, где должно произойти конверсия. Вот простой пример: < /p>
Код: Выделить всё
#include
template
class Template;
class SourceType {};
class TargetType {};
class SpectatorType {};
// forward-declare the convert() so that the function template can look at it
const Template & convert(const Template &);
template
class Template
{
public:
template
operator const U& () const { return convert(*this); }
};
// need the Template class template to be defined
// before this function is defined because we'll need to use its members
const Template & convert(const Template &)
{
// obviously not a real implementation
return *new Template();
}
// function to try the implicit conversion with
void TestFunc(const Template & t)
{}
int main()
{
Template src;
Template spec;
// try to explicitly call the conversion operator, should succeed
src.operator const Template&();
// this should succeed: const Template& should be implicitly convertible to const Template&
TestFunc(src);
// this should fail: const Template& != const Template& and there's no implicit conversion
TestFunc(spec);
return 0;
}
Код: Выделить всё
sfinae-conv-op2.cpp: In member function ‘Template::operator const U&() const [with U = Template; T = TargetType]’:
sfinae-conv-op2.cpp:19:5: warning: infinite recursion detected [-Winfinite-recursion]
19 | operator const U& () const { return convert(*this); }
| ^~~~~~~~
sfinae-conv-op2.cpp:19:48: note: recursive call
19 | operator const U& () const { return convert(*this); }
| ~~~~~~~^~~~~~~
Код: Выделить всё
#include
template
class Template;
class SourceType {};
class TargetType {};
class SpectatorType {};
// disallow conversion by default
template
const Template & convert(const Template &) { static_assert(false, "Not allowed"); }
// explicitly opt-in for relevant types
template
const Template & convert(const Template &);
// type trait for detecting that the class has a nested `type` type
template
struct has_type_member : std::false_type {};
template
struct has_type_member : std::true_type {};
[/b][b]
template
class Template
{
public:
template [/b][b] operator const U& () const { return convert(*this); }
using type = T;[/b]
};
// need the Template class template to be defined
// before this function is defined because we'll need to use its members
const Template & convert(const Template &)
{
// obviously not a real implementation
return *new Template();
}
void TestFunc(const Template & t)
{}
int main()
{
Template src;
Template spec;
// try to explicitly call the conversion operator, should succeed
src.operator const Template&();
// this should succeed: SourceType should be implicitly convertible to TargetType
TestFunc(src);
// this should fail: there's no implicit conversion
TestFunc(spec);
return 0;
}
Подробнее здесь: https://stackoverflow.com/questions/794 ... ith-sfinae
Мобильная версия