I have the following code which seems to work fine on GCC/Clang but with Windows either silently fails at runtime or fails to compile with a duplicate COMDAT error depending on the code.
The crux of the matter is that I have a template function GetSize() that is templated on two different strongly typed enums.
In this sample below, compiling with cl.exe 19.38 will result in a duplicate symbol error for GetSize.
I've seen in production code that this pattern will compile fine but at runtime the GetSizeYEnum::one() will be "incorrectly" called when GetSizeXEnum::b() is expected.
What does the spec say about this?
enum class XEnum
{
a = 0,
b = 1
};
enum class YEnum
{
zero = 0,
one = 1
};
template <YEnum T>
struct V;
template <>
struct V<YEnum::zero>
{
char x[40];
};
template <>
struct V<YEnum::one>
{
char x[50];
};
namespace Debug {
template <XEnum T>
inline constexpr size_t GetSize();
template <> inline constexpr size_t GetSize<XEnum::a>() { return 10; }
template <> inline constexpr size_t GetSize<XEnum::b>() { return 20; }
template <YEnum T>
inline constexpr size_t GetSize() { return sizeof(V<T>); }
}
struct Doer
{
void Perform(size_t v);
template <XEnum T>
void Perform()
{
Perform(Debug::GetSize<T>());
}
template <YEnum T>
void Perform()
{
Perform(Debug::GetSize<T>());
}
};
void Doer::Perform(size_t v)
{
//std::cout << v << std::endl;
v = v + v;
}
int main()
{
// The following 4 static assertions do not fail.
static_assert(Debug::GetSize<XEnum::a>() == 10);
static_assert(Debug::GetSize<XEnum::b>() == 20);
static_assert(Debug::GetSize<YEnum::zero>() == 40);
static_assert(Debug::GetSize<YEnum::one>() == 50);
Doer d;
d.Perform<XEnum::a>();
d.Perform<XEnum::b>();
d.Perform<YEnum::zero>();
d.Perform<YEnum::one>();
return 0;
}
Thanks!
Expected templated function with same definition to work for multiple strongly typed enums types.