[type_traits][function_types] Discard param const qualification, bug or feature?

classic Classic list List threaded Threaded
28 messages Options
12
Reply | Threaded
Open this post in threaded view
|

[type_traits][function_types] Discard param const qualification, bug or feature?

Mostafa-6
Both the type_traits and function_types library discard parameter  
const-qualifiers when decomposing function types. Is this a bug or a  
feature? If a feature, then it's surprising enough behaviour that I think  
it warrants some documentation in both libraries. For the record, I'm  
using gcc 4.7.3 on Cygwin 1.7.22 in Windows 7, and here's a reproducible  
example of what I'm talking about:

#include <boost/type_traits.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/assert.hpp>

using namespace boost;

typedef void (foo)(int const);

int main()
{

   typedef function_traits<foo>::arg1_type traits_deduced_type;
   BOOST_MPL_ASSERT(( is_same<traits_deduced_type, int> ));
   //Errors:
   //BOOST_MPL_ASSERT(( is_same<traits_deduced_type, int const> ));

   typedef boost::function_types::parameter_types<foo> ftypes_params;
   typedef boost::mpl::at<ftypes_params, boost::mpl::int_<0> >::type
     ftypes_deduced_type;
   BOOST_MPL_ASSERT(( is_same<ftypes_deduced_type, int> ));
   //Errors:
   //BOOST_MPL_ASSERT(( is_same<ftypes_deduced_type, int const> ));

   return 0;
}

Mostafa


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Krzysztof Czainski
2013/9/25 Mostafa <[hidden email]>

> Both the type_traits and function_types library discard parameter
> const-qualifiers when decomposing function types. Is this a bug or a
> feature? If a feature, then it's surprising enough behaviour that I think
> it warrants some documentation in both libraries. For the record, I'm using
> gcc 4.7.3 on Cygwin 1.7.22 in Windows 7, and here's a reproducible example
> of what I'm talking about:
>
> #include <boost/type_traits.hpp>
> #include <boost/function_types/**parameter_types.hpp>
> #include <boost/mpl/at.hpp>
> #include <boost/mpl/int.hpp>
> #include <boost/mpl/assert.hpp>
>
> using namespace boost;
>
> typedef void (foo)(int const);
>
> int main()
> {
>
>   typedef function_traits<foo>::arg1_**type traits_deduced_type;
>   BOOST_MPL_ASSERT(( is_same<traits_deduced_type, int> ));
>   //Errors:
>   //BOOST_MPL_ASSERT(( is_same<traits_deduced_type, int const> ));
>
>   typedef boost::function_types::**parameter_types<foo> ftypes_params;
>   typedef boost::mpl::at<ftypes_params, boost::mpl::int_<0> >::type
>     ftypes_deduced_type;
>   BOOST_MPL_ASSERT(( is_same<ftypes_deduced_type, int> ));
>   //Errors:
>   //BOOST_MPL_ASSERT(( is_same<ftypes_deduced_type, int const> ));
>
>   return 0;
> }
>
> Mostafa
>

The two function declarations:
void f(int);
void f(int const);
declare the same function, not an overload. Const added to an argument type
passed by value doesn't change the function signature. It is because the
parameter will be copied anyway, and the const refers to how the argument
will be treated inside the function's implementation.

So in your example, I think the compiler correctly discards the 'const'.

Regards,
Kris

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Rob Stewart-6
On Sep 25, 2013, at 2:57 AM, Krzysztof Czainski <[hidden email]> wrote:

> 2013/9/25 Mostafa <[hidden email]>
>
>> Both the type_traits and function_types library discard parameter const-qualifiers when decomposing function types. Is this a bug or a
>> feature? If a feature, then it's surprising enough behaviour that I think it warrants some documentation in both libraries.

[snip]

>> typedef void (foo)(int const);
>
> The two function declarations:
> void f(int);
> void f(int const);
> declare the same function, not an overload.

Right. Top level const is not part of the function's type.

> Const added to an argument type passed by value doesn't change the function signature. It is because the parameter will be copied anyway, and the const refers to how the argument
> will be treated inside the function's implementation.

Exactly.


___
Rob

(Sent from my portable computation engine)

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Andrey Semashev-2
On Wed, Sep 25, 2013 at 12:48 PM, Rob Stewart <[hidden email]>wrote:

> On Sep 25, 2013, at 2:57 AM, Krzysztof Czainski <[hidden email]>
> wrote:
>
> > 2013/9/25 Mostafa <[hidden email]>
> >
> >> Both the type_traits and function_types library discard parameter
> const-qualifiers when decomposing function types. Is this a bug or a
> >> feature? If a feature, then it's surprising enough behaviour that I
> think it warrants some documentation in both libraries.
>
> [snip]
>
> >> typedef void (foo)(int const);
> >
> > The two function declarations:
> > void f(int);
> > void f(int const);
> > declare the same function, not an overload.
>
> Right. Top level const is not part of the function's type.
>
> > Const added to an argument type passed by value doesn't change the
> function signature. It is because the parameter will be copied anyway, and
> the const refers to how the argument
> > will be treated inside the function's implementation.
>
> Exactly.
>

<complain_mode>

I have to say that while these rules are logical and understandable when
explained, types of function arguments are a constant source of confusion.
The described above quirk with const arguments can be considered quite rare
as people usually don't declare arguments that way. But C++11 brought us
rvalue references, and the following:

  foo(int&& n)
  {
    // n is _not_ rvalue reference here
  }

I understand the rationale for this, and it seems the right thing. But once
in a while, when yet another fellow developer asks me why is that so, I
wonder if it would be better if the standard was more straight-forward in
this part.

</complain_mode>

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Mostafa-6
On Wed, 25 Sep 2013 02:09:19 -0700, Andrey Semashev  
<[hidden email]> wrote:

> On Wed, Sep 25, 2013 at 12:48 PM, Rob Stewart  
> <[hidden email]>wrote:
>
>> On Sep 25, 2013, at 2:57 AM, Krzysztof Czainski <[hidden email]>
>> wrote:
>>
>> > 2013/9/25 Mostafa <[hidden email]>
>> >
>> >> Both the type_traits and function_types library discard parameter
>> const-qualifiers when decomposing function types. Is this a bug or a
>> >> feature? If a feature, then it's surprising enough behaviour that I
>> think it warrants some documentation in both libraries.
>>
>> [snip]
>>
>> >> typedef void (foo)(int const);
>> >
>> > The two function declarations:
>> > void f(int);
>> > void f(int const);
>> > declare the same function, not an overload.
>>
>> Right. Top level const is not part of the function's type.
>>
>> > Const added to an argument type passed by value doesn't change the
>> function signature. It is because the parameter will be copied anyway,  
>> and
>> the const refers to how the argument
>> > will be treated inside the function's implementation.
>>
>> Exactly.
>>

Ah, thanks. I was only thinking in terms of the parameter type.

>
> <complain_mode>
>
> I have to say that while these rules are logical and understandable when
> explained, types of function arguments are a constant source of  
> confusion.

Exactly. That's why an explanatory note or two in the documentation would  
go a long way.

> The described above quirk with const arguments can be considered quite  
> rare
> as people usually don't declare arguments that way.

It can show up in some meta-programming code. Say you want to capture a  
value by const and let the meta-programmed code forward it to some  
destination, and for the sake of efficiency you decided to the forwarding  
by reference. If you're not careful, you can end up with an 'int &' to an  
'int const' in the meta-programmed code.

Mostafa


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Rob Stewart-6
In reply to this post by Andrey Semashev-2
On Sep 25, 2013, at 5:09 AM, Andrey Semashev <[hidden email]> wrote:

> On Wed, Sep 25, 2013 at 12:48 PM, Rob Stewart <[hidden email]>wrote:
>
>> On Sep 25, 2013, at 2:57 AM, Krzysztof Czainski <[hidden email]>
>> wrote:
>>
>>> 2013/9/25 Mostafa <[hidden email]>
>>>
>>>> Both the type_traits and function_types library discard parameter const-qualifiers when decomposing function types. Is this a bug or a
>>>> feature? If a feature, then it's surprising enough behaviour that I think it warrants some documentation in both libraries.
>>
>> [snip]
>>
>>>> typedef void (foo)(int const);
>>>
>>> The two function declarations:
>>> void f(int);
>>> void f(int const);
>>> declare the same function, not an overload.
>>
>> Right. Top level const is not part of the function's type.
>>
>>> Const added to an argument type passed by value doesn't change the function signature. It is because the parameter will be copied anyway, and the const refers to how the argument will be treated inside the function's implementation.
>>
>> Exactly.
>
> I have to say that while these rules are logical and understandable when
> explained, types of function arguments are a constant source of confusion.

There are many things about C++ that are contrary to someone's intuition. That parameter declaration is no different than the following variable:

int const i;

When used with either of the forms of f(), above, does i work any differently than j, below?

int j;

They work alike with either f(), because the int is copied. The difference is whether you can change the int after initialization. The parameters are no different.

> The described above quirk with const arguments can be considered quite rare
> as people usually don't declare arguments that way.

Maybe you're right, but I always do so, by default.

> But C++11 brought us
> rvalue references, and the following:
>
>  foo(int&& n)
>  {
>    // n is _not_ rvalue reference here
>  }
>
> I understand the rationale for this, and it seems the right thing. But once in a while, when yet another fellow developer asks me why is that so, I wonder if it would be better if the standard was more straight-forward in
> this part.

The issue comes down to one of consequences. If n were still an rvalue, within foo(), even when referenced by name, what problems will that cause?


___
Rob

(Sent from my portable computation engine)

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Rob Stewart-6
In reply to this post by Mostafa-6
On Sep 25, 2013, at 10:59 AM, Mostafa <[hidden email]> wrote:

> On Wed, 25 Sep 2013 02:09:19 -0700, Andrey Semashev <[hidden email]> wrote:
>
>> I have to say that while these rules are logical and understandable when
>> explained, types of function arguments are a constant source of confusion.
>
> Exactly. That's why an explanatory note or two in the documentation would go a long way.

Offer a documentation patch and it might be applied.

>> The described above quirk with const arguments can be considered quite rare
>> as people usually don't declare arguments that way.
>
> It can show up in some meta-programming code. Say you want to capture a value by const and let the meta-programmed code forward it to some destination, and for the sake of efficiency you decided to the forwarding by reference. If you're not careful, you can end up with an 'int &' to an 'int const' in the meta-programmed code.

You can create an int & to a copy of an int const, but not to an int const.

___
Rob

(Sent from my portable computation engine)

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Andrey Semashev-2
In reply to this post by Rob Stewart-6
On Thu, Sep 26, 2013 at 1:28 PM, Rob Stewart <[hidden email]>wrote:

> On Sep 25, 2013, at 5:09 AM, Andrey Semashev <[hidden email]>
> wrote:
>
> > I have to say that while these rules are logical and understandable when
> > explained, types of function arguments are a constant source of
> confusion.
>
> There are many things about C++ that are contrary to someone's intuition.
> That parameter declaration is no different than the following variable:
>
> int const i;
>
> When used with either of the forms of f(), above, does i work any
> differently than j, below?
>
> int j;
>
> They work alike with either f(), because the int is copied. The difference
> is whether you can change the int after initialization. The parameters are
> no different.
>

Sure, they work the same, from the caller's perspective. But is that a
reason to cheat with the type system?

void foo(int);
void bar(const int);

typeid(&foo) == typeid(&bar); // why?

My point was that despite the same behavior on the caller's side, the
functions have different signatures, and I don't see why there was a
_necessity_ to force the compiler to drop cv-qualifiers from the function
argument types. In other words, it makes the language more complicated for
no apparent reason.


> > But C++11 brought us
> > rvalue references, and the following:
> >
> >  foo(int&& n)
> >  {
> >    // n is _not_ rvalue reference here
> >  }
> >
> > I understand the rationale for this, and it seems the right thing. But
> once in a while, when yet another fellow developer asks me why is that so,
> I wonder if it would be better if the standard was more straight-forward in
> > this part.
>
> The issue comes down to one of consequences. If n were still an rvalue,
> within foo(), even when referenced by name, what problems will that cause?
>

AFAIR, the motivating example was something like this:

  void bar(int&& n); // moves from n

  void foo(int&& n)
  {
    bar(n);
    bar(n); // moves from a moved-from object
    ++n; // uses a moved-from object
  }

This can be a real gotcha, I admit. But just as well as this:

  class my_class
  {
    vector<int> vec;

  public:
    my_class(vector<int>&& v) : vec(v) // copies the vector, instead of
moving
    {
    }
  };

This latter mistake is usually less critical, but for that reason it is
also more often made and left unnoticed.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Jonathan Wakely-2
On 26 September 2013 11:02, Andrey Semashev wrote:

>
> Sure, they work the same, from the caller's perspective. But is that a
> reason to cheat with the type system?
>
> void foo(int);
> void bar(const int);
>
> typeid(&foo) == typeid(&bar); // why?
>
> My point was that despite the same behavior on the caller's side, the
> functions have different signatures,

No they don't. "Signature" has a specific meaning in C++ and they have
the same signature.

They have different tokens in the declaration, but so do these:

signed long int i;
long j;

That doesn't mean they have different types.


> and I don't see why there was a
> _necessity_ to force the compiler to drop cv-qualifiers from the function
> argument types. In other words, it makes the language more complicated for
> no apparent reason.

There are reasons.

If they were different signatures would you be able to overload based
on top-level const-ness of parameters? Would that be useful?  If the
function takes its arguments by-value why do you (the caller) care
what it does with that parameter?  It should be able to modify it or
not, without that affecting the function signature the caller sees.
Whether the parameter is const or not is an internal detail to the
function, not part of the interface.

Currently template argument deduction is constistent, and doesn't
deduce a top-level const.  If functions didn't ignore top-level const
on parameters would argument deduction have to change to deduce
top-level const-ness? e.g.

template<typename T>
void f(T by_value) { ++by_value; }

int i;
const int ci;

f(i);
f(ci);

Should that call two different template specializations? Doing so
would break the function template in the f(ci) case because T would be
'const int' and non-modifiable.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Andrey Semashev-2
On Thu, Sep 26, 2013 at 2:40 PM, Jonathan Wakely
<[hidden email]>wrote:

> On 26 September 2013 11:02, Andrey Semashev wrote:
> >
> > Sure, they work the same, from the caller's perspective. But is that a
> > reason to cheat with the type system?
> >
> > void foo(int);
> > void bar(const int);
> >
> > typeid(&foo) == typeid(&bar); // why?
> >
> > My point was that despite the same behavior on the caller's side, the
> > functions have different signatures,
>
> No they don't. "Signature" has a specific meaning in C++ and they have
> the same signature.
>

Ok, I used the term "signature" for the lack of a better word.


> They have different tokens in the declaration, but so do these:
>
> signed long int i;
> long j;
>
> That doesn't mean they have different types.
>

Yes, but that's not the case with long and const long, is it?


> > and I don't see why there was a
> > _necessity_ to force the compiler to drop cv-qualifiers from the function
> > argument types. In other words, it makes the language more complicated
> for
> > no apparent reason.
>
> There are reasons.
>
> If they were different signatures would you be able to overload based
> on top-level const-ness of parameters?


The functions with different qualification of arguments would be considered
distinct, yes. Whether or not such declarations would result in compile
time error is another question.


> Would that be useful?


No, the overload would be always ambiguous. Because of this it would
probably be a good idea to always generate an error when such overloads are
found.


>  If the
> function takes its arguments by-value why do you (the caller) care
> what it does with that parameter?


No, and as I said, the top level cv-qualification of function arguments
would still be transparent for the caller. Unless he wants to know the
exact "signature" (I'm using the term loosely here again) of the function.


>  It should be able to modify it or
> not, without that affecting the function signature the caller sees.
> Whether the parameter is const or not is an internal detail to the
> function, not part of the interface.
>

True. I'm not really arguing with that. It's just that the outcome of this
reasoning appears unexpected for newcomers.


> Currently template argument deduction is constistent, and doesn't
> deduce a top-level const.  If functions didn't ignore top-level const
> on parameters would argument deduction have to change to deduce
> top-level const-ness? e.g.
>
> template<typename T>
> void f(T by_value) { ++by_value; }
>
> int i;
> const int ci;
>
> f(i);
> f(ci);
>
> Should that call two different template specializations? Doing so
> would break the function template in the f(ci) case because T would be
> 'const int' and non-modifiable.
>

No, both calls would invoke f<int>(int) with signature void(int).

However, if f was declared like this:

template< typename T >
void f(const T by_value);

then both calls would invoke f<int>(const int) with signature void(const
int).

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Jonathan Wakely-2
On 26 September 2013 12:50, Andrey Semashev wrote:

> On Thu, Sep 26, 2013 at 2:40 PM, Jonathan Wakely
> <[hidden email]>wrote:
>
>
>>  It should be able to modify it or
>> not, without that affecting the function signature the caller sees.
>> Whether the parameter is const or not is an internal detail to the
>> function, not part of the interface.
>>
>
> True. I'm not really arguing with that.

But that's the fundamental reason it's not part of the signature!

> It's just that the outcome of this
> reasoning appears unexpected for newcomers.

If the language changed every time a newcomer finds something
unexpected the standard would be revised daily.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Sergey Zhuravlev
In reply to this post by Mostafa-6
Signature type int(int, const std::string) can be used as parameter for
some compiletime algorithm. For example, algorithm that generate new
signature type with optimal transfer arguments int (int, const
std::string&) or generate signature with all argument references int (int&,
const std::string&)
Can't use type_traits, function_types at that cases, because const be
omitted. This will lead to compiletime error, if function with first
signature call function with second signature and use arguments from
function with first signature for this call.

Signature type void(int, const std::string) can use as types tuple for some
compiletime algorithm. Can't use type_traits, function_types, at that case,
because const be lost.

Signature type void(int, const std::string) can use as parentheses dropper
for "types list", e.g. for macro parameter. (int, const std::string) =>
int, const std::string. Can't use type_traits, function_types, at that
case, because const be lost.

I think default behavior is correct, but need parameter for change this
behavior. At least function_types.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Gavin Lambert
On 9/30/2013 10:44 AM, Quoth Sergey Zhuravlev:
> Signature type int(int, const std::string) can be used as parameter for
> some compiletime algorithm. For example, algorithm that generate new
> signature type with optimal transfer arguments int (int, const
> std::string&) or generate signature with all argument references int (int&,
> const std::string&)
> Can't use type_traits, function_types at that cases, because const be
> omitted. This will lead to compiletime error, if function with first
> signature call function with second signature and use arguments from
> function with first signature for this call.

This was discussed recently; there is no difference between the
following two signatures:

   int func(int a, std::string b);
   int func(int a, const std::string b);

Both describe a function that accepts two parameters and returns an int
value; the first parameter being an int passed by value and the second
parameter being a std::string passed by value.  "const" does nothing to
any outside code -- its only effect is to artificially restrict the
allowed behaviour inside the implementation of the function.  In neither
case can the implementation affect the original string object passed by
the caller (unless the string's copy constructor is broken), so
constness cannot be part of the interface.

ie. it's perfectly valid to declare a function as the first in a header
file and then implement it as the second in a cpp file.

When the string is passed by reference, the presence or absence of
"const" does make a difference, and it should be (and is) preserved.
This *is* an interface detail as it indicates to the caller whether the
object can be modified or not by the implementation.

Can you describe (with code) what your actual problem is and why this is
giving you trouble?



_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Mostafa-6
In reply to this post by Sergey Zhuravlev
On Sun, 29 Sep 2013 14:44:52 -0700, Sergey Zhuravlev  
<[hidden email]> wrote:

> Signature type int(int, const std::string) can be used as parameter for
> some compiletime algorithm. For example, algorithm that generate new
> signature type with optimal transfer arguments int (int, const
> std::string&) or generate signature with all argument references int  
> (int&,
> const std::string&)
> Can't use type_traits, function_types at that cases, because const be
> omitted. This will lead to compiletime error, if function with first
> signature call function with second signature and use arguments from
> function with first signature for this call.

That was exactly the use case and the problem I had. Fortunately for me, I  
was able to specify the return type and parameters_type (as an  
mpl::vector) separately, which solved the issue. But I don't know if this  
is doable in general. For example, what does one do in the following  
scenario:

template <typename T>
struct Foo
{
   void mybar( // Construct efficient argument transfer signature for  
T::bar )
   { T::bar(....); }
};

without forcing the user to seperately specify T::bar paramtypes as a  
separate template parameter?

> Signature type void(int, const std::string) can use as types tuple for  
> some
> compiletime algorithm. Can't use type_traits, function_types, at that  
> case,
> because const be lost.
>
> Signature type void(int, const std::string) can use as parentheses  
> dropper
> for "types list", e.g. for macro parameter. (int, const std::string) =>
> int, const std::string. Can't use type_traits, function_types, at that
> case, because const be lost.
>
> I think default behavior is correct, but need parameter for change this
> behavior. At least function_types.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Rob Stewart-6
On Sep 29, 2013, at 11:00 PM, Mostafa <[hidden email]> wrote:

> On Sun, 29 Sep 2013 14:44:52 -0700, Sergey Zhuravlev <[hidden email]> wrote:
>
>> Signature type int(int, const std::string) can be used as parameter for some compiletime algorithm. For example, algorithm that generate new signature type with optimal transfer arguments int (int, const std::string&) or generate signature with all argument references int (int&,
>> const std::string&)
>
> That was exactly the use case and the problem I had. Fortunately for me, I was able to specify the return type and parameters_type (as an mpl::vector) separately, which solved the issue. But I don't know if this is doable in general. For example, what does one do in the following scenario:
>
> template <typename T>
> struct Foo
> {
>  void mybar( // Construct efficient argument transfer signature for T::bar )
>  { T::bar(....); }
> };
>
> without forcing the user to seperately specify T::bar paramtypes as a separate template parameter?

#include<boost/call_traits.hpp>
...
boost::call_traits<typename T::bar>::param_type

___
Rob

(Sent from my portable computation engine)

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Mostafa-6
On Mon, 30 Sep 2013 05:24:45 -0700, Rob Stewart  
<[hidden email]> wrote:

> On Sep 29, 2013, at 11:00 PM, Mostafa <[hidden email]>  
> wrote:
>
>> On Sun, 29 Sep 2013 14:44:52 -0700, Sergey Zhuravlev  
>> <[hidden email]> wrote:
>>
>>> Signature type int(int, const std::string) can be used as parameter  
>>> for some compiletime algorithm. For example, algorithm that generate  
>>> new signature type with optimal transfer arguments int (int, const  
>>> std::string&) or generate signature with all argument references int  
>>> (int&,
>>> const std::string&)
>>
>> That was exactly the use case and the problem I had. Fortunately for  
>> me, I was able to specify the return type and parameters_type (as an  
>> mpl::vector) separately, which solved the issue. But I don't know if  
>> this is doable in general. For example, what does one do in the  
>> following scenario:
>>
>> template <typename T>
>> struct Foo
>> {
>>  void mybar( // Construct efficient argument transfer signature for  
>> T::bar )
>>  { T::bar(....); }
>> };
>>
>> without forcing the user to seperately specify T::bar paramtypes as a  
>> separate template parameter?
>
> #include<boost/call_traits.hpp>
> ...
> boost::call_traits<typename T::bar>::param_type
>

I should have been more specific, bar is some member function of T. So in  
Foo:mybar, the goal is to reconstruct T::bar's paramtypes as "efficient  
types". That's what the other person's post was also referring to. So if a  
client passes the following struct as a template parameter to Foo:

struct ClientClass
{
   static void bar(int const) { ... }
};

the library is able to instantiate the following Foo::mybar

void Foo::mybar(int const & x) { ClientClass::bar(x); }


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Jonathan Wakely-2
On 30 September 2013 20:22, Mostafa wrote:

>
> I should have been more specific, bar is some member function of T. So in
> Foo:mybar, the goal is to reconstruct T::bar's paramtypes as "efficient
> types". That's what the other person's post was also referring to. So if a
> client passes the following struct as a template parameter to Foo:
>
> struct ClientClass
> {
>   static void bar(int const) { ... }
> };

You're presenting this class as having a function of that type, but it
doesn't, your example is:

struct ClientClass
{
  static void bar(int) { ... }
};

> the library is able to instantiate the following Foo::mybar
>
> void Foo::mybar(int const & x) { ClientClass::bar(x); }

Why do you choose a different "efficient type" for an 'int' parameter
vs a 'const int' parameter?

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Mostafa-6
On Mon, 30 Sep 2013 12:49:44 -0700, Jonathan Wakely  
<[hidden email]> wrote:

> On 30 September 2013 20:22, Mostafa wrote:
>>
>> I should have been more specific, bar is some member function of T. So  
>> in
>> Foo:mybar, the goal is to reconstruct T::bar's paramtypes as "efficient
>> types". That's what the other person's post was also referring to. So  
>> if a
>> client passes the following struct as a template parameter to Foo:
>>
>> struct ClientClass
>> {
>>   static void bar(int const) { ... }
>> };
>
> You're presenting this class as having a function of that type, but it
> doesn't, your example is:
>
> struct ClientClass
> {
>   static void bar(int) { ... }
> };
>
>> the library is able to instantiate the following Foo::mybar
>>
>> void Foo::mybar(int const & x) { ClientClass::bar(x); }
>
> Why do you choose a different "efficient type" for an 'int' parameter
> vs a 'const int' parameter?
>

You're most likely reading this message out of context. If you start with  
Sergey's response it'll probably make more sense.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Jonathan Wakely-2
On 30 September 2013 21:53, Mostafa wrote:
>>
>> Why do you choose a different "efficient type" for an 'int' parameter
>> vs a 'const int' parameter?
>>
>
> You're most likely reading this message out of context. If you start with
> Sergey's response it'll probably make more sense.

No, I've read the whole thread.

It sounds like your code to generate signatures has a bug and doesn't
model the rules of C++.

I repeat: Why would you choose a different "efficient type" for an
'int' parameter vs a 'const int' parameter?

I would say if you're doing that then you're doing something wrong, so
should fix it to remove top-level const, because that's what C++ does
and because it's probably the right thing to do anyway.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [type_traits][function_types] Discard param const qualification, bug or feature?

Mostafa-6
On Mon, 30 Sep 2013 14:20:40 -0700, Jonathan Wakely  
<[hidden email]> wrote:

> On 30 September 2013 21:53, Mostafa wrote:
>>>
>>> Why do you choose a different "efficient type" for an 'int' parameter
>>> vs a 'const int' parameter?
>>>
>>
>> You're most likely reading this message out of context. If you start  
>> with
>> Sergey's response it'll probably make more sense.
>
> No, I've read the whole thread.
>
> It sounds like your code to generate signatures has a bug and doesn't
> model the rules of C++.
>
> I repeat: Why would you choose a different "efficient type" for an
> 'int' parameter vs a 'const int' parameter?
>
> I would say if you're doing that then you're doing something wrong, so
> should fix it to remove top-level const, because that's what C++ does
> and because it's probably the right thing to do anyway.

Ah, ok, I had the use case reversed. Let's try this:

struct SomeUserClass
{
   static void foo(int const x)
   {
     SomeCodeGenClass::foo(x);
   }
};

SomeCodeGenClass::foo is a mere parameter forwarder, so the goal is to do  
it as efficiently as possible. It's signature is constructed from  
SomeUserClass::foo. For correctness, that should be:

void SomeCodeGenClass::foo(int const & x)

But, function_types<SomeUserClass::foo>::arg1_type resolves to int, so  
that add_reference'ing will give the following signature for the TMP  
constructed SomeCodeGenClass::foo

void SomeCodeGenClass::foo(int & x)

Which will give a compiler error for SomeUserClass::foo. Note, this is a  
really watered down example, so if function_types doesn't work with static  
member functions make the functions free, etc...

And I'm not arguing that either type_traits or function_types should  
behave differently, I was wondering if a general solution exists for such  
a situation.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
12