我試圖尋找一些關于這種確切的繼承模式如何作業的解釋,但從未發現任何非常相似的東西,所以我希望你們中的一些人知道發生了什么。
所以這是我想要得到的行為:
#include <iostream>
template <typename T, typename F = std::less<T>>
class Base
{
protected:
F obj;
public:
virtual bool f(T t1, T t2) { return obj(t1, t2); }
};
template <typename T>
struct Derived : public Base<T, std::less<T>>
{
public:
bool f(T t1, T t2) { return this->obj(t2, t1); }
};
int main()
{
Base<int> b;
std::cout << std::boolalpha << b.f(1, 2) << '\n';
Derived<float> d;
std::cout << std::boolalpha << d.f(1, 2) << '\n';
}
f()在這里,我重新定義Derived并更改了類的行為方式。程式列印出來
true
false
就像它應該的那樣。
但是,當我嘗試修改它以便Derived可以采取pair但只比較這樣的.first欄位時
#include <iostream>
template <typename T, typename F = std::less<T>>
class Base
{
protected:
F obj;
public:
virtual bool f(T t1, T t2) { return obj(t1, t2); }
};
template <typename T>
struct Derived : public Base<std::pair<T, T>, std::less<T>>
{
public:
typedef std::pair<T, T> pair;
bool f(pair t1, pair t2) { return this->obj(t1.first, t2.first); }
};
int main()
{
Base<int> b;
std::cout << std::boolalpha << b.f(1, 2) << '\n';
Derived<int> d;
std::cout << std::boolalpha << d.f(std::make_pair(1, 2), std::make_pair(2, 2)) << '\n';
}
編譯器對我來說全是農業:
file.cpp:9:41: error: no match for call to ‘(std::less<int>) (std::pair<int, int>&, std::pair<int, int>&)’
9 | virtual bool f(T t1, T t2) { return obj(t1, t2); }
| ~~~^~~~~~~~
...
/usr/include/c /10/bits/stl_function.h:385:7: note: candidate: ‘constexpr bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = int]’
385 | operator()(const _Tp& __x, const _Tp& __y) const
| ^~~~~~~~
/usr/include/c /10/bits/stl_function.h:385:29: note: no known conversion for argument 1 from ‘std::pair<int, int>’ to ‘const int&’
385 | operator()(const _Tp& __x, const _Tp& __y) const
| ~~~~~~~~~~~^~~
所以很明顯,Base::f()呼叫的是而不是重新定義。但是,為什么在第一個示例中一切都很好并且虛函式按預期運行時會發生這種情況?
uj5u.com熱心網友回復:
virtual表示根據物件的動態型別呼叫Base::f或呼叫。Derived::f
Derived<int>::f你只打電話的事實main并沒有改變,這Base<std::pair<int,int>,std::less<int>::f是無效的。
具有相同問題的一個更簡單的示例是:
#include <utility>
struct base {
virtual std::pair<int,int> foo(std::pair<int,int> x) {
return x x;
}
};
struct derived : base {
std::pair<int,int> foo(std::pair<int,int> x) override {
return x;
}
};
int main() {
derived d;
}
導致錯誤:
<source>: In member function 'virtual std::pair<int, int> base::foo(std::pair<int, int>)':
<source>:6:17: error: no match for 'operator ' (operand types are 'std::pair<int, int>' and 'std::pair<int, int>')
6 | return x x;
| ~^~
| | |
| | pair<[...],[...]>
| pair<[...],[...]>
Compiler returned: 1
根據您實際嘗試實作的目標,您可能想要制作Base::f純虛擬,或提供Basewhen Tis astd::pair或繼承自的專業化Base<std::pair<T,T>,std::less<std::pair<T,T>>>。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/489108.html
