I have a simple template class A, I want to enable a function if some requirements are satisfied.
Solution 1 - requires clause
The first solution I tried is the following:
template <class T>
class A
{
public:
void a(void) requires (same_as<T, int>)
{
std::cout << "a" << std::endl;
};
};
This works pretty well, I can call A<int>().a() but not A<char>().b();. Also IntelliSense correctly report correctly identifies usage errors in Visual Studio.
Then I tried to move the function definition outside the class and I got C2511 compiler error in Visual Studio while in GCC it works fine
template <class T>
class A
{
public:
void a(void) requires (same_as<T, int>);
};
template <class T>
void A<T>::a(void)
requires (same_as<T, int>)
{
std::cout << "a" << std::endl;
}
Do you think my code is incorrect or is it a visual studio compiler bug/incomplete feature?
Solution 2 - static_assert
This solution works in some cases, but of course it would cause compile errors if you try an explicit template instantiation (for example template class A<char>), also IntelliSense would not correctly identify improper usages
template <class T>
class A
{
public:
void a(void);
};
template <class T>
void A<T>::a(void)
{
static_assert(same_as<T, int>);
std::cout << "a" << std::endl;
}
Soluton 3 - enable_if
(wrong)
template <class T>
class A
{
public:
template <std::enable_if_t<same_as<T, int>, bool> = true>
void a(void);
};
template <class T>
template <std::enable_if_t<same_as<T, int>, bool>>
void A<T>::a(void)
{
std::cout << "a" << std::endl;
}
This solution has the same probelms as #2, moreover I would prefer not to add some non understandable at first sight templates.
Solution 4 - some weird compile time inheritance
template <class T>
class A_base { /*common stuff*/ };
template <class T>
class A : public A_base<T>
{
public:
A_base<T>::A_base;
/* non-int stuff*/
};
template <>
class A<int> : public A_base<int>
{
public:
A_base<int>::A_base;
void a(void) {};
};
This would work well, but it could get quite complex in some situations and very unpleasant for debugging when a bunch of levels are nested
Do you have any advice / better solution?
Thanks in advance
Edit:
- solution #3 does not work, I made a mistake;
- I am using msvc 16.7.0, Build Tools x64/x86 (v14.27)