Is it possible to make CTAD work for T
in this case?
enum class boundary_type:int{inclusive, exclusive};
template<class T, boundary_type left, boundary_type right>
struct interval
{
using value_type = T;
T begin;
T end;
};
I tried to add the decuction guide
template<boundary_type left, boundary_type right, class T>
interval(T, T) -> interval<T, left, right>;
But still gets error
wrong number of template arguments (2, should be 3)
when trying
interval<boundary_type::inclusive, boundary_type::exclusive>{0, 2}
CodePudding user response:
CTAD cannot work with the partially explicitly specified template parameter. But you can do this using normal template function
template<boundary_type left, boundary_type right, class T>
auto make_interval(T begin, T end) {
return interval<T, left, right>{begin, end};
}
int main() {
auto intval = make_interval<boundary_type::inclusive,
boundary_type::exclusive>(0, 2);
}
CodePudding user response:
With a bit more code you could allow the user to use a similar syntax by providing wrapper types for the boundaries containing information about the boundaries on information provided by those wrappers:
enum class boundary_type :int { inclusive, exclusive };
template<class T>
struct exclusive
{
static constexpr ::boundary_type boundary_type = ::boundary_type::exclusive;
using value_type = T;
explicit exclusive(T bound)
: m_bound(bound)
{
}
operator T() const
{
return m_bound;
}
T m_bound;
};
template<class T>
struct inclusive
{
static constexpr boundary_type boundary_type = ::boundary_type::inclusive;
using value_type = T;
inclusive(T bound)
: m_bound(bound)
{
}
operator T() const
{
return m_bound;
}
T m_bound;
};
template<class T, boundary_type left, boundary_type right>
struct interval
{
using value_type = T;
T begin;
T end;
};
template<class Left, class Right>
interval(Left, Right) -> interval<
std::common_type_t<typename std::remove_cvref_t<Left>::value_type, typename std::remove_cvref_t<Right>::value_type>,
std::remove_cvref_t<Left>::boundary_type,
std::remove_cvref_t<Right>::boundary_type
>;
usage
interval intrvl{ inclusive(0), exclusive(2) };
static_assert(std::is_same_v<decltype(intrvl), interval<int, boundary_type::inclusive, boundary_type::exclusive>>);