admin管理员组文章数量:1404924
using
declaration is common and works for other member methods including constructor, but for conversion operator it seems not so simple.
GCC has syntax using base::operator base
to introduce, which denied by Clang.
Declare a forward function is accepted by both compilers, but which is a little complicated IMO.
example was tested with gcc 14.2.0 & clang 19.1.7, std=c++20. SFINAE inheritance rejects by clang.
struct base {
template <typename T> requires (std::is_integral_v<T>)
operator T() const { printf("to int\n"); return 0; }
};
struct derived: base {
//using base::operator; // denied by clang & gcc
//using base::operator base; // denied by clang
template <typename T> requires (std::is_floating_point_v<T>)
operator T() const { printf("to float\n"); return 0; }
// both accept
template <typename T> requires requires { (T) std::declval<base>(); }
operator T() const { return base::operator T(); }
};
derived D;
(int) D; // -> to int
(float) D; // -> to float
using
declaration is common and works for other member methods including constructor, but for conversion operator it seems not so simple.
GCC has syntax using base::operator base
to introduce, which denied by Clang.
Declare a forward function is accepted by both compilers, but which is a little complicated IMO.
example was tested with gcc 14.2.0 & clang 19.1.7, std=c++20. SFINAE inheritance rejects by clang.
struct base {
template <typename T> requires (std::is_integral_v<T>)
operator T() const { printf("to int\n"); return 0; }
};
struct derived: base {
//using base::operator; // denied by clang & gcc
//using base::operator base; // denied by clang
template <typename T> requires (std::is_floating_point_v<T>)
operator T() const { printf("to float\n"); return 0; }
// both accept
template <typename T> requires requires { (T) std::declval<base>(); }
operator T() const { return base::operator T(); }
};
derived D;
(int) D; // -> to int
(float) D; // -> to float
Share
Improve this question
edited Mar 9 at 15:54
Pete Becker
76.6k8 gold badges80 silver badges169 bronze badges
asked Mar 9 at 8:28
YuxaiYuxai
1481 silver badge6 bronze badges
0
2 Answers
Reset to default 5Conversion function templates are one of the few things that you cannot be found by a using-declaration ([namespace.udecl] p1):
Each using-declarator in a using-declaration names the set of declarations found by lookup ([basic.lookup.qual]) for the using-declarator, except that [...], conversion function templates with a dependent return type are ignored, and [...].
The fact that GCC accepts using base::operator base;
is known bug 29027, which has been unresolved since 2006.
Your workaround is already okay, but could be slightly improved:
struct base {
// use concept instead of requires with type trait
template <std::integral T>
operator T() const { printf("to int\n"); return 0; }
};
struct derived: base {
// also use concept here
template <std::floating_point T>
operator T() const { printf("to float\n"); return 0; }
// use std::convertible_to, which checks that implicit conversion is possible,
// not just explicit conversion (like in your "(T) ..." test)
template <typename T> requires std::convertible_to<base, T>
operator T() const { return base::operator T(); }
};
Using-declaration:
A using-declaration cannot refer to a namespace, to a scoped enumerator(until C++20), to a destructor of a base class or to a specialization of a member template for a user-defined conversion function.
So, you'll have to resort to workarounds, like the one you've currently got.
本文标签:
版权声明:本文标题:c++ - what is the best way to introduce template conversion operator `operator T ()` from base class - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744874764a2629849.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论