Saya menghapus semua yang tidak berhubungan dengan pertanyaan Anda (Anda harus melakukan itu untuk membuatnya lebih mudah mendapatkan bantuan), dan inilah yang harus saya kerjakan. Pertama, saya memindahkan milidetik sebelum argumen variadik. Ini dapat membingungkan kompiler di mana paket parameter berakhir, jadi Anda biasanya ingin ... menjadi yang terakhir dalam daftar argumen.
Kedua, CTAD (Pengurangan argumen templat kelas) tidak berfungsi untuk Anda karena kebutuhan untuk mengonversi lambda Anda menjadi fungsi std::sebelum dapat cocok.
Jika main() meneruskan std::function aktual ke konstruktor Anda seperti yang diharapkan, maka ia berfungsi:
auto timer = Timer(
std::function<void(int, int, float)>([](int a, int b, float c) { }),
500ms, 15, 17, 12.0f);
Tapi itu bisa dibilang terlihat lebih buruk daripada yang Anda coba sebelumnya.
Perbaikan yang lebih baik, yang agak tidak jelas, adalah membantu CTAD mengetahui apa yang Anda lakukan dengan panduan pengurangan c++17. Ini adalah pencocokan pola yang mengatakan, jika mereka mencoba membuat kelas ini menggunakan sintaks ini, itu berarti tipenya ini.
Berikut panduan yang menurut saya cocok untuk Anda:
template <typename T, typename... Args>
Timer(T&&, std::chrono::milliseconds, Args...) -> Timer<Args...>;
Apa yang dilakukan panduan ini adalah: mereka dapat meneruskan T&& apa pun sebagai parameter pertama dan diabaikan begitu saja, dan itu diikuti oleh krono milidetik, lalu beberapa tipe lainnya dalam paket Args. Mengingat itu, tipe Timer sebenarnya (kanan panah) hanyalah Timer‹Args...› apa pun itu. Kemudian dilanjutkan, dan fungsi Anda hanya perlu diubah menjadi fungsi std::.
Sekarang ini mencocokkan penggunaan Anda dengan lambda, membuat instance Timer dengan Args yang diberikan, dan dari situ ia dapat mengonversi lambda Anda ke fungsi std::.
Berikut ini contoh yang berfungsi, tanpa semua hal yang tidak terkait:
#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);
}
Penjelajah Kompiler: https://godbolt.org/z/Wa3oK3
person
Chris Uzdavinis
schedule
29.10.2020