This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: SFINAE question 2


On 22 August 2012 19:49, Onay Urfalioglu wrote:
> The following code compiles fine with g++-4.7.1 in c++11 mode, but I think
> it should give errors for the last source line "auto res2 = 2 *
> std::list<int>();" (SFINAE ?)

I don't think it should.

> // compile cmd:
> // g++ c++11-test.cpp -o cpp11-test -std=c++11
>
> #include <vector>
> #include <list>
>
> template<typename T>
> struct HasRandomAccessOp {
>     HasRandomAccessOp(const T &v) {
>         typedef decltype(v[0]) test_type;

This type is only used in the body of the constructor. That means the
constructor must be instantiated for the error to be detected.

>     }
> };
>
> template<typename T, typename T_VECTOR>
> int operator*(const T &l, const T_VECTOR &r) {
>     typedef decltype(HasRandomAccessOp<T_VECTOR>(r))
> random_access_test_type;

The constructor doesn't need to be instantiated for decltype to know
the type of that expression, the type is obviously
HasRandomAccessOp<T_VECTOR>.

Even if the constructor was instantiated, SFINAE would not apply,
because the error happens in the function body, not in the context
where template argument deduction takes place, i.e. in determining the
function signature by substituting the template arguments for the
function parameter types and return type.

>     return 1;
> }
>
> int main() {
>     std::vector<int> iv = {1,2};
>
>     auto res1 = 1 * iv;
>     auto res2 = 2 * std::list<int>();
> }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]