friend and enable_if in operator%

This code is not compiling:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
template<typename T> 
	class Number
{
	T value;
public:
	[[nodiscard]] explicit Number(const T& t)
		: value(t)
	{
	}
	template<typename U>
	friend std::enable_if<std::is_floating_point<U>::value, Number<U>>::type
		operator%(const Number<U>& left, const Number<U>& other)
	{
		return Number<U>(fmod(left.value, other.value));
	}

	template<typename U>
	friend std::enable_if<std::is_integral<U>::value, Number<U>>::type
		operator%(const Number<U>& left, const Number<U>& other)
	{
		return Number<U>(left.value % other.value);
	}

};
void use()
{
	Number<double> a{ 5.55 }, b{ 7.7 };
	Number<double> q = a % b;
	Number<double> t{ 9 }, r{ 18 };
	Number<double> z = t % r;
	Number<int> i{ 4 }, j{ 5 };
	Number<int> k = i % j;
}



It works perfectly fine if operator% is a member function of Number<T>



somehow putting friend before enable_if is making life impossible for the compiler.

What is hapenning?

Regards,
Juan
Came to look at this since no one has for a while now.

But first, and you should know this by now, crank up your compiler warnings and fix the problems listed.

At the very minimum, you should have typename in front of the std::enable_if.


OK, now for your problem: I did not know what was wrong, but I learned online is:
https://stackoverflow.com/a/41730088/2706707

rustyx wrote:
SFINAE works at template instantiation level, i.e. at class Number<T>, not at the level of individual members of the template. Number<int> is a valid instantiation and as such it instantiates the declarations of all 3 members of the class, duplicating the latter 2.

It is not that the two definitions conflict with each other - it is that each definition conflicts with itself (example: http://rextester.com/XRLN87339) (more details: https://stackoverflow.com/questions/6972368/stdenable-if-to-conditionally-compile-a-member-function).
Modified to use JUANDENT’s example

In rustyx’s SO posting he continues to list some workarounds, but it might be simplest to just make the functions non-friend member functions.

Alas. IDK what to offer you better.

Good luck!
Duthomhas wrote:
At the very minimum, you should have typename in front of the std::enable_if.

Since C++20 I don't think it's necessary to use typename here.
Heh, well, ye learn something new every day. (I’m still using C++17 for everything.)

Sorry Juan.
Topic archived. No new replies allowed.