Jul*_*ian 5 c++ constructor explicit-constructor implicit-conversion c++14
我正在用 C++14 绘制一个小的通用类型包装器模板,它旨在使用 mixins 启用、禁用或扩展底层类型的接口。
这是这个包装器的代码(精简了一点):
namespace detail {
/// Helper template that is forwarded to the mixins used
/// for the extension of wrapper<•> in order to enable
/// access to the actual type `Derived`
template <typename Derived>
struct Cast {
using type = Derived;
template <typename T>
static constexpr Derived& self(T* self) { return *static_cast<Derived*>(self); }
template <typename T>
static constexpr Derived const& self(T const* self) { return *static_cast<Derived const*>(self); }
};
/// This helper template is used to derive from all the Mixins
/// one after another, making sure the constructor is mixed in as well:
template <typename Cast, typename T,template <typename...> class...Mixins>
struct wrapper_impl;
template <typename Cast, typename T,template <typename...> class First, template <typename...> class...Rest>
struct wrapper_impl<Cast, T, First, Rest...>
: First<Cast, T>
, wrapper_impl<Cast, T, Rest...>
{
using First<Cast, T>::First;
using wrapper_impl<Cast, T, Rest...>::wrapper_impl;
};
template <typename Cast, typename T, template <typename...> class First>
struct wrapper_impl<Cast, T, First>
: First<Cast, T>
, wrapper_impl<Cast, T>
{
using First<Cast, T>::First;
using wrapper_impl<Cast, T>::wrapper_impl;
};
template <typename Cast, typename T>
struct wrapper_impl<Cast, T> {
};
}
template <typename T, typename Tag, template <typename...> class...Mixins>
class wrapper : public detail::wrapper_impl<detail::Cast<wrapper<T,Tag,Mixins...>>, T, Mixins...> {
public:
using value_type = T;
using detail::wrapper_impl<detail::Cast<wrapper<T,Tag,Mixins...>>, T, Mixins...>::wrapper_impl;
T& get() { return *reinterpret_cast<T*>(&m_buffer); }
T const& get() const { return *reinterpret_cast<T const*>(&m_buffer); }
template <typename...Args>
void construct(Args&&...args) {
new (&m_buffer) T(std::forward<Args>(args)...);
}
void destruct() {
get().~T();
}
~wrapper() {
destruct();
}
private:
std::aligned_storage_t<sizeof(T), alignof(T)> m_buffer;;
};
Run Code Online (Sandbox Code Playgroud)
现在,我可以T使用以下混合模板混合某种类型的构造形式:
template <typename T>
struct constructor_from {
template <typename Cast, typename U>
struct mixin {
explicit mixin(T const& value) {
Cast::self(this).construct(U{value});
}
};
};
Run Code Online (Sandbox Code Playgroud)
到目前为止,这很好,例如我可以int像这样包装:
using my_int = wrapper<int, struct Tag, constructor_from<int>::mixin>;
my_int instance{42};
Run Code Online (Sandbox Code Playgroud)
在Godbolt上查看完整代码。但是,我想禁用不需要的隐式转换,这就是我将构造函数标记为constructor_from::mixinas 的原因explicit。但出乎意料的是,以下内容似乎仍然可以在 clang-5.0.0 上编译而没有错误(参见compiler-explorer):
using my_int = wrapper<int, struct Tag, constructor_from<int>::mixin>;
my_int instance{4.2};
Run Code Online (Sandbox Code Playgroud)
explicit在 clang-5.0.0 上有构造函数?或者我可能误解了构造函数继承的工作原理?正如@someprogrammerdude 指出的那样,我可能误解了explicit构造。但是,我仍然不明白为什么上面的代码应该编译,而这不:
struct foo {
explicit foo(int) {}
};
struct bar : foo {
using foo::foo;
};
int main() {
bar instance{4.2};
}
Run Code Online (Sandbox Code Playgroud)
如果有人可以将我指向 c++ 标准中允许在 my 情况下进行构造的相应部分wrapper,但在此处的情况下阻止它,那就太好了
| 归档时间: |
|
| 查看次数: |
360 次 |
| 最近记录: |