Smaller than tiny proposal: RaiiCaps

287 views
Skip to first unread message

Rob Meijer

unread,
Mar 27, 2013, 6:21:27 PM3/27/13
to std-pr...@isocpp.org
A few months ago I wrote a blog post about a potential singleton alternative that I dubbed RAII-Caps (capability like references for access to the constructor of resource management (RAI) classes.


Although I'm rather embarrassed by the small size of the actual code needed for this proposal (a few lines only and small lines at that), I believe it may be an extremely  modest useful addition to the standard library.

template <typename T>
class raiicap {
  public:
    friend int main(int,char **);
  private:
    raiicap(){}
};

My proposal thus is the addition of this tiny raiicap template to the standard library.


 

Nicol Bolas

unread,
Mar 27, 2013, 9:03:43 PM3/27/13
to std-pr...@isocpp.org

So you've developed a class that is only useful via dependency injection, can only be used within the direct context of `main` (and only one version of main at that), and in the end, it only provides half of the singleton concept. And it doesn't even really do that, since `main` is perfectly capable of constructing more than one of them.

There are far better ways to restrict the construction of an object instance to one or more specific functions than this.

Lawrence Crowl

unread,
Mar 27, 2013, 9:44:00 PM3/27/13
to std-pr...@isocpp.org
On 3/27/13, Nicol Bolas <jmck...@gmail.com> wrote:
> On Wednesday, March 27, 2013 3:21:27 PM UTC-7, pibara wrote:
>>
>> A few months ago I wrote a blog post about a potential singleton
>> alternative that I dubbed RAII-Caps (capability like references for access
>>
>> to the constructor of resource management (RAI) classes.
>>
>>
>> http://minorfs.wordpress.com/2013/01/18/raiicap-pattern-injected-singleton-alternative-for-c/
>>
>> Although I'm rather embarrassed by the small size of the actual code
>> needed for this proposal (a few lines only and small lines at that), I
>> believe it may be an extremely modest useful addition to the standard
>> library.
>>
>> template <typename T>
>> class raiicap {
>> public:
>> friend int main(int,char **);
>> private:
>> raiicap(){}
>> };
>>
>> My proposal thus is the addition of this tiny raiicap template to the
>> standard library.
>
> So you've developed a class that is only useful via dependency injection,
> can only be used within the direct context of `main` (and only one version
> of main at that), and in the end, it only provides *half* of the singleton
> concept. And it doesn't even really do that, since `main` is perfectly
> capable of constructing more than one of them.
>
> There are far better ways to restrict the construction of an object
> instance to one or more specific functions than this.

Please elaborate.

--
Lawrence Crowl

Rob Meijer

unread,
Mar 28, 2013, 1:20:13 AM3/28/13
to std-pr...@isocpp.org



2013/3/28 Nicol Bolas <jmck...@gmail.com>
The concept is that main, using this simple template class can be made the 'initial source of authority' for constructing RAII objects for scares resources. It can not "only be USED within the direct context of `main`", it's a token of authority that can only ORIGINATE within the direct context of `main` from where it can be discretionary delegated to other parts of the program, for example an object who's responsibility it is to instantiate only a single instance, or even to instantiate only a single instance AND provide a global access point to it.
 
There are far better ways to restrict the construction of an object instance to one or more specific functions than this.

Could you elaborate?

 
 
 
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.
 
 

Nicol Bolas

unread,
Mar 28, 2013, 5:10:04 AM3/28/13
to std-pr...@isocpp.org
On Wednesday, March 27, 2013 10:20:13 PM UTC-7, pibara wrote:



2013/3/28 Nicol Bolas <jmck...@gmail.com>
On Wednesday, March 27, 2013 3:21:27 PM UTC-7, pibara wrote:
A few months ago I wrote a blog post about a potential singleton alternative that I dubbed RAII-Caps (capability like references for access to the constructor of resource management (RAI) classes.


Although I'm rather embarrassed by the small size of the actual code needed for this proposal (a few lines only and small lines at that), I believe it may be an extremely  modest useful addition to the standard library.

template <typename T>
class raiicap {
  public:
    friend int main(int,char **);
  private:
    raiicap(){}
};

My proposal thus is the addition of this tiny raiicap template to the standard library.


So you've developed a class that is only useful via dependency injection, can only be used within the direct context of `main` (and only one version of main at that), and in the end, it only provides half of the singleton concept. And it doesn't even really do that, since `main` is perfectly capable of constructing more than one of them.


The concept is that main, using this simple template class can be made the 'initial source of authority' for constructing RAII objects for scares resources. It can not "only be USED within the direct context of `main`", it's a token of authority that can only ORIGINATE within the direct context of `main` from where it can be discretionary delegated to other parts of the program, for example an object who's responsibility it is to instantiate only a single instance, or even to instantiate only a single instance AND provide a global access point to it.

When I said that it "can only be used within the direct context of `main`," I meant `raiicap`, not the classes that use it. You can't do anything with `raiicap` outside of `main`. And again, this only works with one version of `main`.

I understand quite well what you're trying to do. I'm saying that not everyone wants singletons to be allocated by `main`. And what of code that uses `int main()`, which is just as standard C++ as `int main(int argc, const char *argv)`? There's also a fair amount of code out there that doesn't use `main` at all; either they're using `WinMain` or they're being called by some other library that itself uses `main`. You're effectively saying that none of this code can use your helper class.

If a significant number of C++ users would have to invent their own version of `raiicap` in order to use the arbitrary, then what good is it? If a user cannot force `raiicap` to use a specific function, rather than just one form of `main`, then you've limited the use cases for this tools a lot.

And what of the people who want to split up their `main` functions, perhaps because they're getting rather big? What if it's more natural to put that initialization in some other function that's called by `main`?

Main is not the center of everyone's universe. Your tool is too restrictive. And C++ doesn't offer a way to generalize it to a user-provided function without employing macros. So I don't think it's a good tool.

There are far better ways to restrict the construction of an object instance to one or more specific functions than this.

Could you elaborate?

The same way you're doing it here, only without an intermediate, dependency-injected object. Make the class's constructors of interest private and make the "one or more specific functions" that can allocate them friends.

That way, it is the writer of the class who gets to decide which functions get to create it. You're not limited to one specific form of `main`.

Rob Meijer

unread,
Mar 29, 2013, 3:54:18 AM3/29/13
to std-pr...@isocpp.org
2013/3/28 Nicol Bolas <jmck...@gmail.com>
On Wednesday, March 27, 2013 10:20:13 PM UTC-7, pibara wrote:



2013/3/28 Nicol Bolas <jmck...@gmail.com>

On Wednesday, March 27, 2013 3:21:27 PM UTC-7, pibara wrote:
A few months ago I wrote a blog post about a potential singleton alternative that I dubbed RAII-Caps (capability like references for access to the constructor of resource management (RAI) classes.


Although I'm rather embarrassed by the small size of the actual code needed for this proposal (a few lines only and small lines at that), I believe it may be an extremely  modest useful addition to the standard library.

template <typename T>
class raiicap {
  public:
    friend int main(int,char **);
  private:
    raiicap(){}
};

My proposal thus is the addition of this tiny raiicap template to the standard library.


So you've developed a class that is only useful via dependency injection, can only be used within the direct context of `main` (and only one version of main at that), and in the end, it only provides half of the singleton concept. And it doesn't even really do that, since `main` is perfectly capable of constructing more than one of them.


The concept is that main, using this simple template class can be made the 'initial source of authority' for constructing RAII objects for scares resources. It can not "only be USED within the direct context of `main`", it's a token of authority that can only ORIGINATE within the direct context of `main` from where it can be discretionary delegated to other parts of the program, for example an object who's responsibility it is to instantiate only a single instance, or even to instantiate only a single instance AND provide a global access point to it.

When I said that it "can only be used within the direct context of `main`," I meant `raiicap`, not the classes that use it. You can't do anything with `raiicap` outside of `main`.

The raiicap is a discretionary token of authority that 'originates' at main, making logical computational root and the compositional root conveniently fall together, and allowing the authority to use the constructor to be passed around in a discretionary way. So saying that you can't do anything with raiicap outside of main is like saying you can't do anything with a factory created object outside of the factory. 
 
And again, this only works with one version of `main`.


Yes, this should be fixed, any version of main as defined in the standard should indeed be included as a friend.
 
I understand quite well what you're trying to do. I'm saying that not everyone wants singletons to be allocated by `main`.

The usecase is  a RAIIish 'alternative' to the 'limited or single resource' part Singletons that does not imply the 'global access' part of the Singleton pattern. So if people 'want' Singletons fall outside of the intended audience, and 'creating a Singleton' falls outside of the usecase.
 
And what of code that uses `int main()`, which is just as standard C++ as `int main(int argc, const char *argv)`?

Agreed.
 
There's also a fair amount of code out there that doesn't use `main` at all; either they're using `WinMain` or they're being called by some other library that itself uses `main`. You're effectively saying that none of this code can use your helper class.

The standard provides us with 'main' as a logical computational root that we can use as compositional root concerning the authority to construct RAII objects. I propose the above as a facility that uses this logical computational root. 

If a specific compiler or a framework provides an alternative logical computational root that falls outside of the standard and that effectively disables delegation of authority from the standard defined main to the compiler/framework specific computational root, than that would indeed be a problem. Do you have details  on how important compilers and frameworks obscure and inhibit the use of the standard defined main for the user?
For compiler builders I would think there should not be much of a problem to allow them to add an extra friend definition to raiicap (for example to winmain) for the version of the standard library that ships with their compiler, but maybe this is a no-go, I don't know.

If a significant number of C++ users would have to invent their own version of `raiicap` in order to use the arbitrary, then what good is it? If a user cannot force `raiicap` to use a specific function, rather than just one form of `main`, then you've limited the use cases for this tools a lot.

I disagree, the user should not be able to force `raiicap` to use an arbitrary function. The creator of a compiler or a framework that inhibits the direct use of main by the user should ideally however be able to do discretionary delegation of its authority to construct arbitrary raiicaps. Depending on the existence of important real-life frameworks that would need this and dependent on the ability of compiler vendors to extend the stl defined types, it may be a good idea for me to look into this and see if I can write an extended proposal that allows for this. In any case its essential that the creator of a library that defines RAII classes should have no notion of the
framework, compiler etc that uses it. 
 

And what of the people who want to split up their `main` functions, perhaps because they're getting rather big? What if it's more natural to put that initialization in some other function that's called by `main`?

There is no problem there.

 
Main is not the center of everyone's universe. Your tool is too restrictive. And C++ doesn't offer a way to generalize it to a user-provided function without employing macros. So I don't think it's a good tool.

Basically discretionary delegation is what makes the tool flexible. User provided functions would brake the model and render the pattern useless. It might however be usefull to change the proposal as to allow the delegation of a full 'root of authority' by framework builders.
 

There are far better ways to restrict the construction of an object instance to one or more specific functions than this.

Could you elaborate?

The same way you're doing it here, only without an intermediate, dependency-injected object. Make the class's constructors of interest private and make the "one or more specific functions" that can allocate them friends.

That way, it is the writer of the class who gets to decide which functions get to create it.
 
What business does 'the writer of the class' have 'statically' determining what function gets to create it. My proposal allows the writer of the class to state: "The creator of the 'program' gets to do discretionary delegate the right to create".

Rob Meijer

unread,
Mar 29, 2013, 7:42:55 AM3/29/13
to std-pr...@isocpp.org
An updated version for facilitating the framework scenario:

template <typename T>
class raiicap {
    raiicap() {}
  public:
    raiicap(raiicap<void> const&) {}
    friend int main(int,char **);
};

This could than for example be used like:

void use(resource &r) {
  r.use();
};

void allocate_and_use(raiicap<resource> const &authority_to_allocate_specific_resource) {
    resource r(authority_to_allocate_specific_resource);
    use(r);
};

void frameworkmain(raiicap<void> const &authority_to_allocate_any_resource){
    raiicap<resource> authority_to_allocate_specific_resource(authority_to_allocate_any_resource);
    allocate_and_use(authority_to_allocate_specific_resource);
};

int main(int argc,char**argv) {
  raiicap<void> authority_to_allocate_any_resource;
  frameworkmain(authority_to_allocate_any_resource);
};

Next to the original:

int main(int argc,char**argv) {
  raiicap<resource> authority_to_allocate_specific_resource();
  allocate_and_use(authority_to_allocate_specific_resource);
};




2013/3/29 Rob Meijer <pib...@gmail.com>

Klaim - Joël Lamotte

unread,
Mar 29, 2013, 8:03:13 AM3/29/13
to std-pr...@isocpp.org
I think limiting to main() is a mistake. I have a lot of code which would benefit from a way to force the type to be used only 
by one non-main function OR one other type. A variation of your type which allow specifying which function or type is the only user of the CRTP type would be far more useful.

Joel Lamotte

Nicol Bolas

unread,
Mar 29, 2013, 9:31:28 PM3/29/13
to std-pr...@isocpp.org
On Friday, March 29, 2013 12:54:18 AM UTC-7, pibara wrote:
2013/3/28 Nicol Bolas <jmck...@gmail.com>
There's also a fair amount of code out there that doesn't use `main` at all; either they're using `WinMain` or they're being called by some other library that itself uses `main`. You're effectively saying that none of this code can use your helper class.

The standard provides us with 'main' as a logical computational root that we can use as compositional root concerning the authority to construct RAII objects. I propose the above as a facility that uses this logical computational root.

`main` is not a "logical computational root". It isn't even the first code that is required to be executed in a C++ application. It is merely the first code that can assume that all globally-accessible objects have been initialized.

My point is that this method only works if `main` is the root of your application's code. It doesn't have to be, and people for whom this isn't true would be unable to use your code, even if they did have a root.
 
If a specific compiler or a framework provides an alternative logical computational root that falls outside of the standard and that effectively disables delegation of authority from the standard defined main to the compiler/framework specific computational root, than that would indeed be a problem. Do you have details  on how important compilers and frameworks obscure and inhibit the use of the standard defined main for the user?

Well, since that would include a healthy percentage of Windows applications, I'm guessing that it's a non-trivial number. Not to mention every application plugin or DLLs in general.
 
For compiler builders I would think there should not be much of a problem to allow them to add an extra friend definition to raiicap (for example to winmain) for the version of the standard library that ships with their compiler, but maybe this is a no-go, I don't know.

If a significant number of C++ users would have to invent their own version of `raiicap` in order to use the arbitrary, then what good is it? If a user cannot force `raiicap` to use a specific function, rather than just one form of `main`, then you've limited the use cases for this tools a lot.

I disagree, the user should not be able to force `raiicap` to use an arbitrary function. The creator of a compiler or a framework that inhibits the direct use of main by the user should ideally however be able to do discretionary delegation of its authority to construct arbitrary raiicaps.

So, you want everyone to rewrite their frameworks and such, all to accommodate a type that someone can just rewrite flawlessly in less than a minute?

And of course, that doesn't deal with the C frameworks that call into C++ code, where such delegation is simply impossible.

Depending on the existence of important real-life frameworks that would need this and dependent on the ability of compiler vendors to extend the stl defined types, it may be a good idea for me to look into this and see if I can write an extended proposal that allows for this. In any case its essential that the creator of a library that defines RAII classes should have no notion of the
framework, compiler etc that uses it. 
 
Main is not the center of everyone's universe. Your tool is too restrictive. And C++ doesn't offer a way to generalize it to a user-provided function without employing macros. So I don't think it's a good tool.

Basically discretionary delegation is what makes the tool flexible. User provided functions would brake the model and render the pattern useless. It might however be usefull to change the proposal as to allow the delegation of a full 'root of authority' by framework builders.
 

There are far better ways to restrict the construction of an object instance to one or more specific functions than this.

Could you elaborate?

The same way you're doing it here, only without an intermediate, dependency-injected object. Make the class's constructors of interest private and make the "one or more specific functions" that can allocate them friends.

That way, it is the writer of the class who gets to decide which functions get to create it.
 
What business does 'the writer of the class' have 'statically' determining what function gets to create it.
 
It's their class. The owner of a class has the right to determine who gets to create it. That's what your entire construct relies upon: the owner of the class must use this `raiicap` tag to force users to only create the object if they have authorization to do so.

The only difference is who decides who has that authorization. In your case, it's delegated to some other class. In my case, it's determined on a class-by-class basis. So each class can decide, for themselves, who gets to create them.
 
My proposal allows the writer of the class to state: "The creator of the 'program' gets to do discretionary delegate the right to create".

"But only if the user has direct, modifiable access to `main`."

Jonathan Wakely

unread,
Apr 4, 2013, 12:27:31 PM4/4/13
to std-pr...@isocpp.org
Enforcing "Parameterise from Above" instead of the reprehensible Singleton is nice, and this is a handy utility for a particular subset of PfA use cases, but it is too specific to those particular use cases and doesn't belong in the standard.


Bb Hh

unread,
Apr 13, 2013, 11:11:53 PM4/13/13
to std-pr...@isocpp.org
The ::main is particular. IIRC the standard forbids the "use" of global main. There might be some non-trivial work to do, though I'm not sure if there is any implementation depending on this.


2013/4/5 Jonathan Wakely <c...@kayari.org>
Enforcing "Parameterise from Above" instead of the reprehensible Singleton is nice, and this is a handy utility for a particular subset of PfA use cases, but it is too specific to those particular use cases and doesn't belong in the standard.



--
Reply all
Reply to author
Forward
0 new messages