Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prefer some function over ADL

I want to use range-based for to iterate over the unicode code points in a UTF8 encoded std::string. I have defined my own begin and end in the global namespace but the begin and end in the std namespace are being preferred (i.e. those found by ADL). Is there any way to prefer my own functions?

Example:

const char* begin(const std::string& s) {
    std::cout << "BEGIN";
    return s.data();
}

const char* end(const std::string& s) {
    std::cout << "END";
    return s.data() + s.length();
}

int main() {
    std::string s = "asdf";

    for (char c : s)
        std::cout << c;
}

I want it to print BEGINENDasdf (or ENDBEGINasdf) but it prints asdf.

Is there no other way than to do a manual for using a qualified name?

like image 573
uk4321 Avatar asked Dec 14 '13 05:12

uk4321


People also ask

What ADL means?

Activities of Daily Living (ADLs): Activities of daily living are activities related to personal care. They include bathing or showering, dressing, getting in and out of bed or a chair, walking, using the toilet, and eating.

What are daily life functions?

The basic ADLs (BADL) or physical ADLs are those skills required to manage one's basic physical needs, including personal hygiene or grooming, dressing, toileting, transferring or ambulating, and eating.

What is ADL dependence?

ADL dependence Dependence is defined as receiving help from another person (use of an assistive device by itself does not constitute dependency) to complete the activity. We included five basic ADLs: bathing, dressing, eating, toileting, and transferring from a bed to a chair.

What is an ADL assessment?

Activities of Daily Living (ADL) assessment evaluates a worker's level of functioning concerning personal care plus recreational and social activities. The process is managed by an occupational therapist and should be preferably conducted in the worker's home environment.


1 Answers

Wrap std::string in your own type. By making it a template you can customise any existing container and add your own range logic to it. It's not even that different from your first attempt.

#include <string>
#include <iostream>

template <typename S>
struct custom_container {
    S &s_;

    custom_container (S &s) : s_(s) {}

    auto begin() -> decltype(s_.begin()) {
        std::cout << "BEGIN";
        return s_.begin();
    }

    auto end() -> decltype(s_.end()) {
        std::cout << "END";
        return s_.end();
    }
};

template <typename S>
custom_container make_container (S &s) {
     return custom_container <S> (s);
}


int main () {
    std::string t = "asdf";
    auto s = make_container(t);

    for (char c : s) {
        std::cout << c;
    }
}

Outputs

BEGINENDasdf

like image 88
Anthony Avatar answered Oct 09 '22 10:10

Anthony