ฉันแยกทุกอย่างที่ไม่เกี่ยวข้องกับคำถามของคุณออก (คุณควรทำอย่างนั้นเพื่อให้ขอความช่วยเหลือได้ง่ายขึ้น) และนี่คือสิ่งที่ฉันต้องทำ อันดับแรก ฉันย้ายมิลลิวินาทีก่อนอาร์กิวเมนต์ที่แปรผัน มันอาจทำให้คอมไพลเลอร์สับสนเมื่อแพ็กพารามิเตอร์สิ้นสุด ดังนั้นคุณมักจะต้องการให้ ... เป็นสิ่งสุดท้ายในรายการอาร์กิวเมนต์
ประการที่สอง CTAD (การหัก arg เทมเพลตคลาส) ไม่ทำงานสำหรับคุณเนื่องจากจำเป็นต้องแปลงแลมบ์ดาของคุณเป็น std::function ก่อนจึงจะสามารถจับคู่ได้
หาก main() ส่งผ่าน std::function จริงไปยัง Constructor ของคุณตามที่คาดไว้ มันจะใช้งานได้:
auto timer = Timer(
std::function<void(int, int, float)>([](int a, int b, float c) { }),
500ms, 15, 17, 12.0f);
แต่นั่นอาจดูแย่กว่าสิ่งที่คุณลองในตอนแรก
การแก้ไขที่ดีกว่าซึ่งค่อนข้างคลุมเครือคือการช่วยให้ CTAD ทราบว่าคุณกำลังทำอะไรกับ คำแนะนำการหักเงิน c++17 นี่เป็นการจับคู่รูปแบบที่บอกว่า หากพวกเขาพยายามสร้างคลาสนี้โดยใช้ไวยากรณ์ นี้ ก็หมายความว่าคลาสนั้นเป็นประเภท นี้ จริงๆ
คำแนะนำที่ฉันพบว่าใช้ได้ผลสำหรับคุณมีดังนี้
template <typename T, typename... Args>
Timer(T&&, std::chrono::milliseconds, Args...) -> Timer<Args...>;
สิ่งที่คู่มือนี้ทำคือบอกว่า พวกเขาสามารถส่ง T&& อะไรก็ได้เป็นพารามิเตอร์แรก และมันจะถูกละเว้น และตามด้วยโครโนมิลลิวินาที จากนั้นก็มีประเภทอื่นๆ ในแพ็ค Args เนื่องจากประเภทเฉียบพลันของ Timer (ทางขวาของลูกศร) จึงเป็นเพียง Timer‹Args...> ไม่ว่าจะเป็นอะไรก็ตาม จากนั้นจะดำเนินการต่อไป และฟังก์ชันของคุณจะต้องแปลงเป็น std::function ได้
ตอนนี้มันตรงกับการใช้งานของคุณกับแลมบ์ดา สร้างอินสแตนซ์ Timer ด้วย Args ที่กำหนด และจากนั้นก็รู้ว่ามันสามารถแปลงแลมบ์ดาของคุณเป็น std::function
นี่คือตัวอย่างการทำงาน ลบเนื้อหาทั้งหมดที่ไม่เกี่ยวข้อง:
#include <functional>
#include <chrono>
using namespace std::chrono_literals;
template<typename ...Args>
struct Timer {
Timer(std::function<void(Args...)> func, std::chrono::milliseconds step, Args&&... args )
{ }
};
template <typename T, typename... Args>
Timer(T&&, std::chrono::milliseconds, Args...) -> Timer<Args...>;
int main() {
auto timer = Timer([](int a, int b, float c) { }, 500ms, 15, 17, 12.0f);
}
คอมไพเลอร์สำรวจ: https://godbolt.org/z/Wa3oK3
person
Chris Uzdavinis
schedule
29.10.2020