Re: SFINAE question 2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 22 August 2012 21:37, Jonathan Wakely <jwakely.gcc@xxxxxxxxx> wrote:
> 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>();
>> }

You could do something like this instead:

template<typename T>
struct HasRandomAccessOp {
    typedef decltype(std::declval<T>()[0]) test_type;
};

template<typename T, typename T_VECTOR,
         typename = typename HasRandomAccessOp<T_VECTOR>::test_type>
int operator*(const T &l, const T_VECTOR &r) {
    return 1;
}

Now the invalid type occurs in a context where SFINAE applies, so the
function is removed from the overload set for types without a suitable
operator[].


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux