C++: template có thể dùng như exception không?

Mình có 1 hàm viết như sau viết theo ellipsis

int sum_Of_3_or_More(int count, …){

}

count phải là 3 hoặc hơn, nếu không thì hàm sẽ không chạy. Thông thường thì mình sẽ dùng exception

throw std::invalid_argument("3 hoặc nhiều hơn");

Mình thắc mắc không biết dùng template có thể bắt buộc người dùng phải truyền vào coun >= 3 không?

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";
}
2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?