Issue
Why does the code below compile with MSVC2022, but not with GCC 12?
#include <iostream>
template <auto value>
class getter;
template <class T, class ReturnType, ReturnType(T::* func_ptr)() const>
class getter<func_ptr>
{
public:
using object_type = T;
using value_type = ReturnType;
constexpr ReturnType operator() (const T& val) const
{
return (val.*func_ptr)();
}
};
template <class T, class Field, Field T::* field_ptr>
class getter<field_ptr>
{
public:
using object_type = T;
using value_type = Field;
constexpr const Field& operator() (const T& val) const
{
return val.*field_ptr;
}
};
struct A
{
A() = default;
explicit A(size_t k) : key(k), attribute(k + 1)
{
}
size_t key;
size_t attribute;
size_t GetKey() const
{
return key;
}
const size_t & GetKeyRef() const
{
return key;
}
};
int main()
{
auto g1 = getter<&A::key>();
auto g2 = getter<&A::GetKey>();
A a(5);
std::cout << g1(a) << " " << g2(a) << std::endl;
return 0;
}
GCC errors:
MyTest.cpp: In function ‘int {anonymous}::main()’:
MyTest.cpp:66:38: error: ambiguous template instantiation for ‘class {anonymous}::getter<&{anonymous}::A::GetKey>’
66 | auto g2 = getter<&A::GetKey>();
| ^
MyTest.cpp:14:11: note: candidates are: ‘template<class T, class ReturnType, ReturnType (T::* func_ptr)() const> class {anonymous}::getter<func_ptr> [with T = {anonymous}::A; ReturnType = long unsigned int; ReturnType (T::* func_ptr)() const = &{anonymous}::A::GetKey]’
14 | class getter<func_ptr>
| ^~~~~~~~~~~~~~~~
MyTest.cpp:28:11: note: ‘template<class T, class Field, Field T::* field_ptr> class {anonymous}::getter<field_ptr> [with T = {anonymous}::A; Field = long unsigned int() const; Field T::* field_ptr = &{anonymous}::A::GetKey]’
28 | class getter<field_ptr>
| ^~~~~~~~~~~~~~~~~
MyTest.cpp:66:38: error: invalid use of incomplete type ‘class {anonymous}::getter<&{anonymous}::A::GetKey>’
66 | auto g2 = getter<&A::GetKey>();
| ^
MyTest.cpp:11:11: note: declaration of ‘class {anonymous}::getter<&{anonymous}::A::GetKey>’
11 | class getter;
| ^~~~~~
MyTest.cpp: At global scope:
MyTest.cpp:63:9: warning: ‘int {anonymous}::main()’ defined but not used [-Wunused-function]
63 | int main()
| ^~~~
ninja: build stopped: subcommand failed.
Solution
This seems to be a gcc bug as the specialization getter<func_ptr>
is more specialized than the other specialization getter<field_ptr>
for &A::GetKey
.
Answered By - user12002570 Answer Checked By - Dawn Plyler (WPSolving Volunteer)