Here's a minimal code example to show what I'm attempting that works, but not how I'd like it to:
#include <string>
#include <type_traits>
#include <iostream>
struct string_tag {
using R=const std::string;
};
struct int_tag {
using R=const int;
};
template <bool TS>
class Wibble {
public:
template<typename TAG>
typename TAG::R getValue(TAG);
};
template <bool TS>
template <typename TAG>
typename TAG::R Wibble<TS>::getValue(TAG) {
if constexpr (std::is_same<TAG, string_tag>::value) {
return "hello";
}
if constexpr (std::is_same<TAG, int_tag>::value) {
return 42;
}
}
// instantiate classes
template class Wibble<true>;
template class Wibble<false>;
int main () {
Wibble<true> tw;
Wibble<false> fw;
std::cout << "tw string: " << tw.getValue(string_tag{}) << std::endl;
std::cout << "tw int: " << tw.getValue(int_tag{}) << std::endl;
std::cout << "fw string: " <<fw.getValue(string_tag{}) << std::endl;
std::cout << "fw int: " << fw.getValue(int_tag{}) << std::endl;
}
The part I want to change is the ugly function template definition with all the constexpr
logic. I'd like to be able to define the different specializations in TAG
standalone, but doing this gives me redefinition of ...
errors.
Syntax like the following would be nice:
template<bool TS>
template<>
string_tag::R Wibble<TS>::getValue(string_tag) {
return "hello";
}
but computer says "no".