có, và dùng static_assert luôn cho nó báo lỗi khi biên dịch, khỏi mất công đụng tới runtime exception
parameter pack có operator sizeof... cho biết kích thước của nó, viết 1 cái hàm ktra kích cỡ phải >= 3, rồi truyền vô implement ẩn trong 1 namespace nào đó.
#include <iostream>
namespace impl
{
int sumOf3OrMore(int a)
{
return a;
}
template <class ...Ts>
int sumOf3OrMore(int n, Ts... ts)
{
return n + impl::sumOf3OrMore(ts...);
}
}
template <class... Ts>
int sumOf3OrMore(Ts... ts)
{
static_assert(sizeof...(ts) >= 3, "3 hoặc nhiều hơn");
return impl::sumOf3OrMore(ts...);
}
int main()
{
std::cout << sumOf3OrMore(11, 22, 33) << "\n";
std::cout << sumOf3OrMore(11, 22, 33, 44, 55) << "\n";
//std::cout << sumOf3OrMore(11, 22) << "\n"; // báo lỗi khi biên dịch
}
viết kiểu này dù có truyền số thực vào thì nó cũng bị convert thành int, nếu muốn giữ đúng kiểu số thực thì mất công hơn :V
à ko mất công hơn bao nhiêu @_@ có auto sướng
#include <iostream>
#include <typeinfo>
#include <string>
namespace impl
{
template <class T>
T sumOf3OrMore(T t)
{
return t;
}
template <class... Ts, class T>
auto sumOf3OrMore(T n, Ts... ts)
{
return n + impl::sumOf3OrMore(ts...);
}
}
template <class... Ts>
auto sumOf3OrMore(Ts... ts)
{
static_assert(sizeof...(ts) >= 3, "3 hoặc nhiều hơn");
return impl::sumOf3OrMore(ts...);
}
int main()
{
// lỗi biên dịch: 3 hoặc nhiều hơn
//std::cout << sumOf3OrMore(11, 22) << "\n";
auto a = sumOf3OrMore(11, 22, 33);
std::cout << a << " " << typeid(a).name() << "\n";
auto b = sumOf3OrMore(11.5, 22, 33);
std::cout << b << " " << typeid(b).name() << "\n";
auto c = sumOf3OrMore(11.5f, 22, 33);
std::cout << c << " " << typeid(c).name() << "\n";
auto d = sumOf3OrMore(11.5f, 22.5, 33);
std::cout << d << " " << typeid(d).name() << "\n";
// lỗi biên dịch vì ko có operator+ giữa const char* và const char*
//std::cout << sumOf3OrMore("11.5f", "|", "22.5", "|", "33");
using namespace std::string_literals; //xài string literals (operator""s)
auto e = sumOf3OrMore("11.5f"s, "|"s, "22.5"s, "|"s, "33"s);
std::cout << e << " " << typeid(e).name() << "\n";
}