Karena konsep didefinisikan sebagai predikat waktu kompilasi, apakah mungkin untuk menggunakan kembali predikat ini untuk algoritme waktu kompilasi? Misalnya, apakah mungkin untuk memeriksa apakah semua tipe dalam tuple sesuai dengan konsep? Sejauh yang saya lihat, tidak mungkin untuk meneruskan konsep ke fungsi dengan cara apa pun, jenis apa yang membuat saya kembali menggunakan templat untuk kasus-kasus ini.
#include <type_traits>
template<typename T>
concept FloatLike = std::is_same_v<T, float>;
struct IsFloat
{
template<typename U>
constexpr static bool test()
{
return FloatLike<U>;
}
};
template<typename Predicate, typename... T>
constexpr bool all_types()
{
return (Predicate::template test<T>() && ...);
}
int main()
{
static_assert(all_types<IsFloat, float, float>());
static_assert(!all_types<IsFloat, float, int>());
}
Apa yang ingin saya lakukan adalah sesuatu seperti ini, jadi saya tidak harus membungkus konsep itu sepanjang waktu untuk dapat menggunakannya:
template<concept Predicate, typename... T>
constexpr bool all_types()
{
return (Predicate<T> && ...);
}
int main()
{
static_assert(all_types<FloatLike, float, float>());
static_assert(!all_types<FloatLike, float, int>());
}
Apakah ada cara untuk lebih dekat dengan ini?
all_types()
dapat secara signifikan disederhanakan menggunakan ekspresi lipat... &&
:return (... && Predicate::template test<Ts>());
Jawaban:
Yah, tidak, tidak juga. Tidak di C ++ 20. Tidak ada gagasan dalam bahasa parameter template konsep hari ini. Bahkan templat variabel tidak dapat digunakan sebagai parameter templat. Jadi, jika memiliki konsep untuk memulai, kita tidak dapat menghindari pembungkus.
Tapi yang bisa kita lakukan adalah menulis pembungkus yang lebih sederhana. Jika kita setuju untuk menggunakan ciri tipe "gaya lama" sebagai predikat, khususnya yang berperilaku seperti
std::integral_constant
s, maka kita dapat memiliki definisi "konsep" yang cukup singkat yang dapat digunakan sebagai predikat.Sejauh yang bisa saya dapatkan , itu bagus .
sumber
Jika tujuan Anda adalah "memeriksa apakah semua jenis dalam tupel sesuai dengan konsep" , maka Anda dapat melakukan sesuatu seperti ini:
LIVE DEMO
sumber
AllSame
variadic Anda ? Setiap parameter template dalam paket yang diperkenalkan oleh tipe-kendala secara terpisah sudah dibatasi.*_foo()
?...
padaTs
dan&& ...
yang menggunakan itu. (Jelas namaAllSame
itu kemudian tidak pantas, tetapi saya tidak yakin mengapa saya ingin menyatakan penghitungan dengan unary<int,int,int>
).AllSame
tetapiSameAs
(lihat en.cppreference.com/w/cpp/concepts/same_as ) dan OP ingin memiliki konsep yang mengambil sejumlah variabel templat parameter.std::same_as
. Saya tidak berpikir bagian variadik adalah intinya: itu adalah variabel identitas (yang diinginkan) dari konsep tersebut. Dan poin saya adalah bahwa aspek variadik dari contoh konsep Anda tidak relevan dengan penggunaannya (karena konsep non-variadik sudah berfungsi dengan paket parameter templat).