我知道標題完全是 0 意義,我挑戰您根據問題對其進行編輯。
我有以下包裝 lambda 運算式(從它們繼承)并使用它們operator()'s進行多載。
#include <iostream>
template<typename... F>
struct OverloadSet : public F...
{
OverloadSet(F&&... f) : F(std::forward<F>(f))...{}
using F::operator() ...;
};
template<typename... T>
auto overloads(T...t) {
return OverloadSet<T...>(std::forward<T>(t)...);
}
auto s = overloads(
[](int s) {std::cout << typeid(s).name() << " " << s << std::endl; },
[](double d) {std::cout << typeid(d).name() << " " << d << std::endl; }
);
int main()
{
auto s = overloads(
[](int s) {std::cout<<typeid(s).name()<<" " << s << std::endl; },
[](double d) {std::cout << typeid(d).name() << " "<< d << std::endl; }
);
s(3);
s(3.2);
}
代碼復制自C 設計模式書(強烈推薦)
我觀察到建構式引數是多余的,因為我們只需要operator()'s基類。
所以我做了一個確切的例子,但使用更溫和的建構式:
OverloadSet(F&&... f) {}
從這一點來看,我很難理解這個程式是否格式錯誤,因為不同編譯器的反應不同:
海灣合作委員會 11.2
Output of x86-64 gcc 11.2 (Compiler #1)
In instantiation of 'OverloadSet<F>::OverloadSet(F&& ...) [with F = {<lambda(int)>, <lambda(double)>}]':
required from 'auto overloads(T ...) [with T = {<lambda(int)>, <lambda(double)>}]'
required from here
error: use of deleted function '<lambda(int)>::<lambda>()'
叮當(最新)
error: constructor for 'OverloadSet<(lambda at <source>:16:2),
(lambda at <source>:17:2)>' must explicitly initialize the base class '(lambda at <source>:16:2)' which does not have a default constructor
OverloadSet(F&&... f) {}// F(std::forward<F>(f))...{}
MSVC2019(啟用 C 20)
Compiles and prints:
int 3
double 3.2
所以問題是:
- 程式是否完善?
- 如果沒有,如果我們只使用基類的 operator() ,為什么我們需要轉發引數?
uj5u.com熱心網友回復:
我猜 lambda 沒有默認建構式。
更像是這樣:
class A {
public:
A(int a) {}
};
class B {
public:
B(double b) {}
};
class C : public A, public B {
public:
C() {} // error
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/362183.html
