Best templates questions in July 2011

std::basic_string specialization

4 votes

I need to override only length function from std::basic_string because it's not correct for a custom char type on a specific platform. This is current declaration for, let's say, CustomString

typedef STL::basic_string<CustomChar, STL::char_traits<CustomChar>, STL::allocator<CustomChar> > CustomString;

I need to have a class that behaves as CustomString, but with the length function changed.

You need to specialise the std::char_traits structure and override its static size_t length(const char_type* s); function to do that.

Then you don’t even need to specify all the template parameters when instantiating a basic_string. The following definition should be enough:

typedef std::basic_string<CustomChar> CustomString;

Argument deduction for template member functions does not work for classes declared inside function?

4 votes
struct Test
{
        template <class T>
        void print(T& t)
    {
        t.print();
    }
};

struct A
{
    void print() {printf( "A");}
};

struct B
{
    void print() {printf( "B");}
};

void test_it()
{   
    A a;
    B b;

    Test t;
    t.print(a);
    t.print(b);
}

This compiles fine.

struct Test
{
        template <class T>
        void print(T& t)
    {
        t.print();
    }
};


void test_it()
{   
    struct A
    {
        void print() {printf( "A");}
    };

    struct B
    {
        void print() {printf( "B");}
    };

    A a;
    B b;

    Test t;
    t.print(a);
    t.print(b);
}

This fails with error : no matching function for call to 'Test::print(test_it()::A&)'

Can anyone explain me why this happen ? Thanks!!!

In your second example, A and B are local types, which can't be used as template type arguments in C++03 as per §14.3.1/2:

A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter.

A folder where to put "global" shared partial templates

3 votes

I am using Ruby on Rails 3.0.7 and I am planning to use partial templates. All classes in my application would use same partials so I have to decide where to located all those.

Is it a good idea to put "global" shared partial templates in the lib folder? If no, what is a common practice to choose the folder where to put those? Any advice on how to properly name and load that folder?

The standard is placing all shared partials in app/views/shared, and referencing them as

render :partial => 'shared/partial_name'

If you have a standard "row in a list" partial (say, for an index page), you could use a shared partial like:

# To render a single object row:
render :partial => 'shared/item', :locals => { :item => @item }
# Or to render them all:
render :partial => 'shared/item', :collection => @items