Click here to Skip to main content
15,513,793 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
See more:
I'm trying to invoke a template function from inside another template, and the C++ compiler is getting confused trying to parse my code.

Basically what's happening is it can't tell that my function is a template function. It thinks it's a field, so it's interpreting the template open brace "<" for a less than operator.

const size_t chiR = tindexR::value;
auto chR = helpers::convert_channel_depth<tchR,trchR>(channel_unchecked<chiR>());
// this line fails at the first brace, thinking it's operator <

It shouldn't matter, but for context, here's the function definition (it's inside a class)

template<size_t Index>
constexpr inline void channel_unchecked(typename channel_by_index_or_empty<Index>::int_type value) {
    if(0>Index || Index>=channels) return;
    using ch = channel_by_index_or_empty<Index>;
    const typename ch::pixel_type::int_type shval = typename ch::pixel_type::int_type(helpers::order_guard((value<ch::min)?ch::min:(value>ch::max)?ch::max:value))<<ch::bits_to_right;            

I've had something similar happen before calling derived virtual functions when the base class is a template, which I could do simply force by preceding the call with this-> but I don't know how to make the C++ compiler do the right thing *here*

So my question is, how do I force the C++ compiler to interpret the line above as a function rather than a field?

What I have tried:

Here's my current workaround. Instead of calling the function, I've reimplemented it:
// there's a parse error here for some reason if i try to use 
// PixelTypeRhs.channel_unchecked<> where it thinks it's 
// an operator < call. I have no idea what to do about that.
// instead, reimplement them here:
const size_t chiR = tindexR::value;
auto chR = helpers::convert_channel_depth<tchR,trchR>(channel_unchecked<chiR>());
const typename PixelTypeRhs::int_type shvalR = 
   typename PixelTypeRhs::int_type(helpers::order_guard((chR<trchR::min)?trchR::min:(chR>trchR::max)?trchR::max:chR))<<trchR::bits_to_right;            

This is undesirable, obviously.
Updated 10-Apr-21 2:31am
Richard MacCutchan 10-Apr-21 7:20am    
I don't know the answer, but I started a thread in the Lounge a week or so ago on this subject. The typename keyword seems to be causing confusion everywhere, rather than making life simpler. And I have yet to see a definitive answer that makes it clear how it should be used. One of the better sites for explaining C++ (with examples) is C++ reference -[^].

Apologies for the resposts ... lots of finger trouble.

1 solution

This is fancier than anything I've done with templates, so I could be off base here. But recently there was a question involving the use of typename to explicitly flag a type within a template, and yours looks related to that, only a little different.

Scroll all the way to the last section of this[^]. You probably need to prefix template to the part that gets interpreted as operator<.
Share this answer
honey the codewitch 10-Apr-21 7:37am    
Thanks. I actually tried that after I posted the question, but I had the syntax wrong. I ended up writing a helper function to disambiguate. It's for the best anyway that I did it that way, in the end. Still, this is the proper solution.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900