Based on the discussion in #3790 I'm looking into adding support for C++11 forwarding references. I'm looking for guidance on the better of two approaches to take for doing this.
Let me explain the problem and possible solutions with an example:
#distutils: language=c++
#distutils: extra_compile_args=-std=c++11
cdef extern from *:
"""
#include <iostream>
void f(int&& t) {
std::cout << "Rvalue" << std::endl;
}
void f(int& t) {
std::cout << "Lvalue" << std::endl;
}
void f(const int& t) {
std::cout << "Const lvalue" << std::endl;
}
template <typename T>
void foo(T&& t) {
f(std::forward<T>(t));
}
"""
cdef void foo[T](T&& t)
cdef int x = 1
foo(1)
foo(x)
Here, foo is a function that accepts a forwarding reference. Based on whether the argument to foo is an lvalue or rvalue, it should dispatch to the appropriate overload of f. Thus, the expected output of this program is:
The C++ code generated by Cython for the above currently looks like this:
__pyx_v_10forwarding_x = 1;
foo<long>(1);
foo<int>(__pyx_v_10forwarding_x); // this line is incorrect currently
Because foo accepts a forwarding reference, the template argument should be of the form:
int& if the corresponding function argument is an lvalue expression
int if the corresponding function argument is an rvalue expression
One solution is to let decltype handle producing the correct template argument. In this case, the C++ code would look like this::
foo<decltype((1))>(1);
foo<decltype((__pyx_v_10forwarding_x))>(__pyx_v_10forwarding_x);
The other solution is for Cython to compute the appropriate template argument a priori. In this case, the C++ code would look like this:
foo<long>(1);
foo<int&>(__pyx_v_10forwarding_x);
Which of these sounds better from a Cython viewpoint?
cc: @da-woods if you have any suggestions here. Thank you :)
Based on the discussion in #3790 I'm looking into adding support for C++11 forwarding references. I'm looking for guidance on the better of two approaches to take for doing this.
Let me explain the problem and possible solutions with an example:
Here,
foois a function that accepts a forwarding reference. Based on whether the argument tofoois an lvalue or rvalue, it should dispatch to the appropriate overload off. Thus, the expected output of this program is:The C++ code generated by Cython for the above currently looks like this:
Because
fooaccepts a forwarding reference, the template argument should be of the form:int&if the corresponding function argument is an lvalue expressionintif the corresponding function argument is an rvalue expressionOne solution is to let
decltypehandle producing the correct template argument. In this case, the C++ code would look like this::The other solution is for Cython to compute the appropriate template argument a priori. In this case, the C++ code would look like this:
Which of these sounds better from a Cython viewpoint?
cc: @da-woods if you have any suggestions here. Thank you :)