Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3211618
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 17, 20262026-05-17T14:45:09+00:00 2026-05-17T14:45:09+00:00

The last question I asked was something I stumbled upon when trying to understanding

  • 0

The last question I asked was something I stumbled upon when trying to understanding another thing… that I also can’t understand (not my day).

This is quite a long question statement, but at least I hope this question might prove useful to many people and not only me.

The code I have is the following:

template <typename T> class V;
template <typename T> class S;

template <typename T>
class V
{
public:
 T x;

 explicit V(const T & _x)
 :x(_x){}

 V(const S<T> & s)
 :x(s.x){}
};

template <typename T>
class S
{
public:
 T &x;

 explicit S(V<T> & v)
 :x(v.x)
 {}
};

template <typename T>
V<T> operator+(const V<T> & a, const V<T> & b)
{
 return V<T>(a.x + b.x);
}

int main()
{
 V<float> a(1);
 V<float> b(2);
 S<float> c( b );

 b = a + V<float>(c); // 1 -- compiles
 b = a + c;           // 2 -- fails
 b = c;               // 3 -- compiles

 return 0;
}

Expressions 1 and 3 work perfectly, while expression 2 does not compile.

If I have understood properly, what happens is:

Expression 1

  1. c is is implicitly converted to const by using a standard conversion sequence (consisting on just one qualification conversion).
  2. V<float>(const S<T> & s) is called and a temporal the const V<float> object generated (let’s call it t). It is already const-qualified because it is a temporal value.
  3. a is converted to const similarly to c.
  4. operator+(const V<float> & a, const V<float> & b) is called, resulting in a temporal of type const V<float> that we can call q.
  5. the default V<float>::operator=(const & V<float>) is called.

Am I OK up to here? If I made even the most subtle mistake please, let me know, for I am trying to gain an understanding about implicit casting as deep as possible…

Expression 3

  1. c is converted to V<float>. For that, we have a user-defined conversion sequence:
    1.1. first standard conversion: S<float> to const S<float> via qualification conversion.
    1.2. user-defined conversion: const S<float> to V<float> via V<float>(const S<T> & s) constructor.
    1.3 second standard conversion: V<float> to const V<float> via qualification conversion.
  2. the default V<float>::operator=(const & V<float>) is called.

Expression 2?

What I do not understand is why there is a problem with the second expression. Why is the following sequence not possible?

  1. c is converted to V<float>. For that, we have a user-defined conversion sequence:
    1.1. initial standard conversion: S<float> to const S<float> via qualification conversion.
    1.2. user-defined conversion: const S<float> to V<float> via V<float>(const S<T> & s) constructor.
    1.3. final standard conversion: V<float> to const V<float> via qualification conversion.
  2. Steps 2 to 6 are the same as in case of expression 1.

After reading the C++ standard I though: ‘hey! maybe the problem has to to with 13.3.3.1.2.3!’ which states:

If the user-defined conversion is specified by a template conversion function, the second standard conversion sequence must have exact match rank.

But that cannot be the case since the qualification conversion has exact match rank…

I really have no clue…

Well, whether you have the answer or not, thanks you for reading up to here 🙂

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-17T14:45:09+00:00Added an answer on May 17, 2026 at 2:45 pm

    As Edric pointed out, conversions are not considered during template argument deduction. Here, you have two contexts where the template parameter T can be deduced from the type of the arguments:

    template<class T>
    v<T> operator+(V<T> const&, V<T> const&);
                   ~~~~~~~~~~~  ~~~~~~~~~~~~
    

    But you try to invoke this function template with a V<float> on the left-hand side and an S on the right hand side. Template argument deduction results in T=float for the left hand side and you’ll get an error for the right hand side because there is no T so that V<T> equals S<T>. This qualifies as a template argument deduction failure and the template is simply ignored.

    If you want to allow conversions your operator+ shouldn’t be a template. There is the following trick: You can define it as an inline friend inside of the class template for V:

    template<class T>
    class V
    {
    public:
       V();
       V(S<T> const&); // <-- note: no explicit keyword here
    
       friend V<T> operator+(V<T> const& lhs, V<T> const& rhs) {
          ...
       }
    };
    

    This way, the operator is not a template anymore. So, there is no need for template argument deduction and your invocation should work. The operator is found through ADL (argument dependent lookup) because the left-hand side is a V<float>. The right-hand side is properly converted to a V<float> as well.

    It is also possible to disable template argument deduction for a specific argument. For example:

    template<class T>
    struct id {typedef T type;};
    
    template<class T>
    T clip(
       typename id<T>::type min,
       T value,
       typename id<T>::type max )
    {
       if (value<min) value=min;
       if (value>max) value=max;
       return value;
    }
    
    int main() {
       double x = 3.14;
       double y = clip(1,x,3); // works, T=double
    }
    

    Even though the type of the first and last argument is an int, they are not considered during template argument deduction because id<T>::type is not a so-called *deducible context`. So, T is only deduced according to the second argument, which results in T=double with no contradictions.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

This is also a question that I asked in a comment in one of
This question has been asked here in one form or another but not quite
Apologies if this question has been asked before. I'm hoping that someone can step
I guess this is a continuation of the last question I asked: bulk insert
This is similar to this question I asked last week. My dataGrid is populated
I previously asked a question about fetching the last 100 mentions for a person
My last question wasn't explained very well. What I'm trying to do here is
Let me rephrase my last question, what PHP library or framework can I use
In my last question I asked how to best send a string from one
Ok, building off of the last question I asked , How does Mysql handle

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.