SFINAE question 2

Jonathan Wakely jwakely.gcc@gmail.com
Wed Aug 22 21:07:00 GMT 2012


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>();
> }



More information about the Gcc-help mailing list