問題
我有一個簡單的 CRTP 模式類BaseInterface和兩個派生自此類的類:test_dint和test_dint2.
test_dint和test_dint2- 在dtor中test_dint顯式宣告為~test_dint() = default;.
我嘗試<std::intptr_t, test_dint>通過呼叫 std::make_pair 來使用型別制作 std::pair 并且編譯失敗并出現錯誤:
- MSVC -
error C2440: '<function-style-cast>': cannot convert from 'initializer list' to '_Mypair' - CLang 11 -
error: no matching constructor for initialization of '__pair_type' (aka 'pair<long, test_dint>')
但是,如果成對的型別更改為<std::intptr_t, test_dint2>- 所有編譯都沒有錯誤。
我無法理解 - 為什么顯式 dtor 宣告會改變 std::pair 模板的行為?
完整代碼
#include <memory>
#include <unordered_map>
template<typename DerivedT>
class enable_down_cast
{
public:
DerivedT const& impl() const
{
// casting "down" the inheritance hierarchy
return *static_cast<DerivedT const*>(this);
}
DerivedT& impl()
{
return *static_cast<DerivedT*>(this);
}
//~enable_down_cast() = default;
protected:
// disable deletion of Derived* through Base*
// enable deletion of Base* through Derived*
~enable_down_cast() = default;
private:
using Base = enable_down_cast;
};
template<typename Impl>
class BaseInterface : public enable_down_cast<Impl>
{
public:
using handle_type = std::intptr_t;
BaseInterface() = default;
// Disable copy
BaseInterface(const BaseInterface&) = delete;
BaseInterface& operator=(const BaseInterface&) = delete;
// Enable move
BaseInterface(BaseInterface&&) = default;
BaseInterface& operator=(BaseInterface&&) = default;
~BaseInterface() = default;
handle_type handle() const
{
return m_handle;
}
protected:
handle_type m_handle{ 0 };
private:
using enable_down_cast<Impl>::impl;
};
class test_dint : public BaseInterface<test_dint> {
public:
test_dint() = delete;
test_dint(const handle_type handle) :
BaseInterface<test_dint>()
{
m_handle = handle;
}
~test_dint() = default;
};
class test_dint2 : public BaseInterface<test_dint2> {
public:
test_dint2() = delete;
test_dint2(const handle_type handle) :
BaseInterface<test_dint2>()
{
m_handle = handle;
}
};
int main()
{
test_dint::handle_type handle = 100500;
std::make_pair(handle, test_dint{ handle }); // <--- failed ctor
std::make_pair(handle, test_dint2{ handle });
return 0;
}
現場演示
https://godbolt.org/z/eee7h47v7
uj5u.com熱心網友回復:
這是因為當您宣告解構式時,您會阻止編譯器生成移動建構式,因此test_dint不再可移動構造(也不能復制構造,因為它是基礎)。
明確宣告它將使其作業。
test_dint(test_dint&&)=default;
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/445341.html
上一篇:當向量可以解決問題時,為什么默認使用雙端佇列作為堆疊的底層容器?
下一篇:基于型別的建構式模板特化
