Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug?] Ambiguous template specialization with a custom formatter for a template class #3209

Closed
nlg550 opened this issue Nov 28, 2022 · 1 comment

Comments

@nlg550
Copy link

nlg550 commented Nov 28, 2022

Hello,

I was integrating the {fmt} library into my project and encounter the following issue: the compilation fails due to ambiguous partial template specialization when I include fmt/ranges.h and a template class have the methods begin(), end() and a custom formatter defined. For example,

#include <vector>

#include <fmt/format.h>
#include <fmt/ranges.h>

template<typename T>
struct Matrix {
	using iterator = typename std::vector<T>::iterator;
	
	int nrows;
	int ncols;
	std::vector<T> internal;
	
	Matrix(int rows, int cols, std::initializer_list<T> ilist) : nrows(rows), ncols(cols), internal(ilist)
	{}
	
	T operator()(int i, int j) const {
		return internal[j + i * ncols];
	}
	
	iterator begin() {
		return internal.begin();
	}
	
	iterator end() {
		return internal.end();
	}
};

template<typename T>
struct fmt::formatter<Matrix<T>>
{
	formatter<T> entry_fmt;
	
	template<typename ParseContext>
	constexpr auto parse(ParseContext& ctx) {
		return entry_fmt.parse(ctx);
	}
	
	template<typename FormatContext>
	auto format(const Matrix<T>& mat, FormatContext& ctx) {
		auto output = ctx.out();
		
		for (int i = 0; i < mat.nrows; ++i) {
			for (int j = 0; j < mat.ncols; ++j) {
				output = entry_fmt.format(mat(i, j), ctx);
				format_to(output, " ");
			}
			
			format_to(output, "\n");
		}
		
		return output;
	}
};

int main(int argc, char* argv[]) {
    Matrix<float> mat1(3, 3, {1, 2, 3, 4, 5, 6, 7, 8, 9});
	fmt::print("{}", mat1);
	
    return EXIT_SUCCESS;
}

Live demo: https://godbolt.org/z/nY4771soe

Naturally, removing the fmt/ranges.h header, everything works as expected. However, the issue arises when you have multiple classes: one using a custom formatter like this and another that uses a range formatter.

@vitaut
Copy link
Contributor

vitaut commented Nov 28, 2022

Same as #751.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants