Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Workaround for template argument deduction in non-deduced context

Consider the following code:

#include <iostream>

template<class T>
struct outer {
    struct inner {};
};

template<class T>
std::ostream& operator<<(std::ostream & stream, 
                         typename outer<T>::inner const& value) {
    std::cout << "An outer::inner!";
    return stream;
}

int main() {
    outer<float>::inner foo;

    std::cout << foo << std::endl; // does not compile
}

This does not compile, because typename outer<T>::inner is a nondeduced context (as explained here), meaning the template-argument-type cannot be deduced by the compiler (read this answer for the why). As I see it, I have two options to make it work:

  1. Move inner outside of outer and make it a class-template. I prefer this one, because the impact on the using code is smaller.
  2. Add a to_string-method to inner.

Are there any other solutions for this (that do not result in ugly syntax in the using code)?

like image 348
Björn Pollex Avatar asked Nov 29 '11 09:11

Björn Pollex


People also ask

What is template deduction?

Template argument deduction is used when selecting user-defined conversion function template arguments. A is the type that is required as the result of the conversion. P is the return type of the conversion function template.

What is type deduction c++?

Type inference or deduction refers to the automatic detection of the data type of an expression in a programming language. It is a feature present in some strongly statically typed languages. In C++, the auto keyword(added in C++ 11) is used for automatic type deduction.

What is a non type template parameter?

A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument. A non-type parameter can be any of the following types: An integral type. An enumeration type. A pointer or reference to a class object.

Which is a correct example of template parameters?

For example, given a specialization Stack<int>, “int” is a template argument. Instantiation: This is when the compiler generates a regular class, method, or function by substituting each of the template's parameters with a concrete type.


1 Answers

You can move the operator into the inner class body and put friend before it. Then replace the parameter type by just inner.

Another technique is to derive inner from a CRTP base parameterized by inner. Then make the parameter type the CRTP class and cast the parameter reference to the derived inner class, the type of which is given by the template argument you deduce.

like image 56
Johannes Schaub - litb Avatar answered Nov 01 '22 01:11

Johannes Schaub - litb