more on optional traits via ADL
template<typename TypeTag, typename ResourceType>
decltype(unique_t_at(
instance_of<ResourceType>::value,
instance_of<size_t>::value,
TypeTag()))
optional_unique_t_at(
ResourceType && resource,
size_t index,
int)
{
return unique_t_at(
std::forward<ResourceType>(resource),
index,
TypeTag());
}
struct no_indexing_support {};
template<typename TypeTag>
no_indexing_support
optional_unique_t_at(...)
{
return no_indexing_support();
}
template<typename TypeTag>
class unique_t {
private:
typedef
decltype(optional_unique_t_at<TypeTag>(
instance_of<type>::value,
instance_of<size_t>::value,
0))
optional_at_result;
public:
...
optional_at_result operator[](
size_t at) {
return optional_unique_t_at<TypeTag>(
t,
at,
0);
}
private:
type t;
};
Lines 1-24 take care of routing to the trait implementation, when it exists, and a default that provides a suitable error when used. The auto keyword is not used, as a consequence we cannot use the parameters and must synthesize the values used in the decltype. These free-functions are templates and are therefore able to use SFINAE. Here we can see most of the adjustments that were needed to get optional traits working.