From 8311304670800332241
X-Google-Thread: 7894ca11fe,308ef4b41a1062df,start
X-Google-Attributes: gid7894ca11fe,public,usenet
X-Google-NewGroupId: yes
X-Google-Language: ENGLISH,ASCII-7-bit
Path: g2news2.google.com!news2.google.com!newsfeed.stanford.edu!news.kjsl.com!news.alt.net!frodo.cs.rpi.edu!not-for-mail
From: Ben Strasser <mail@ben-strasser.net>
Newsgroups: comp.std.c++
Subject: Dynamic Concepts
Date: Fri,  1 May 2009 22:58:19 CST
Organization: Arcor
Lines: 89
Sender: cppmods@cs.rpi.edu
Approved: stephen.clamage@sun.com
Message-ID: <49fb63a8$0$32671$9b4e6d93@newsspool2.arcor-online.net>
NNTP-Posting-Host: netlab.cs.rpi.edu
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
To: (Usenet)
Return-Path: <cppmods@ruralroute.cs.rpi.edu>
X-Original-Date: Fri, 01 May 2009 23:03:34 +0200
X-Submission-Address: std-c++@netlab.cs.rpi.edu
Xref: g2news2.google.com comp.std.c++:523

Hi,

I've been playing with concepts lately and I am really excited about
seeing them used in the wild.

There is however one thing that bothers me. With their introduction we
now have 2 notions of interfaces: The traditional one with virtual
functions and inheritance and the new concept system. I do understand
that they are from an implementation and optimization point of view 2
very different things, however I don't like to have to choose between
them. I think there should be some way to dynamically bind concepts.

Let me illustrate this with an example. Consider the common InputStream
   hierarchy. Traditionally one would implement this with one base class
InputStream and derive lots of classes like FileInputStream,
SocketInputStream, ...

Another method of realizing this would be to create a concept
InputStream and make the FileInputStream, ... classes be a model of it.

The traditional way provides a lot of flexibility by allowing you to
dynamically interchange different stream types, but comes at the price
of virtual function calls, that are nearly impossible to optimize. There
are situations where this flexibility is needed.

However there are also other situations, where I know that I'll just
open a file, read a few things and close it directly afterwards. Here I
pay for the virtual function calls but have no gain at all.

After a bit of experimenting I came up with the following construct:

auto concept InputStream<typename Stream>{
    char get();
};

class FileInputStream{
    char get();
};

class DynamicInputStream{
    virtual char get()=0;
};

template<InputStream InStream>
class DynamicInputStreamChild:public DynamicInputStream{
    InStream in;
    char get(){return in.get();}
};

Helper functions can now be written using the concept style. For example:

template<InputStream In>
String read_string(In&in){
    ...
}

The following code can now be inlined and optimized all the way down to
the underlaying system calls.

FileInputStream in(...);
foo(read_string(in));

When I need the flexibility I can still get it though

void bar(DynamicInputStream&in){
     foo(read_string(in));
}
...
FileInputStream in(...);
auto dyn_in = DynamicInputStreamChild<FileInputStream>(in);
bar(dyn_in);

  From a functional point of view this seems like an optimal solution to
me. (There may however be some problems when the concept uses free
standing functions though.) The thing I dislike is the need for quiet a
bit of boilerplate code and the duplication of the interface
description. In an ideal world the compiler would generate this binding
part for me. I do realize, that it's too late for that in C++0x by now.
However I'm interested in hearing the opinions of other people and if
there might be a better way to solve this problem.

Ben Strasser

-- 
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]



