I have a class, Property
, that has two template parameters: the type of the property, and whether or not the property is optional (i.e. might not exist).
The code I've written to represent this logic looks like this:
#include<type_traits>
#include<optional>
#include<iostream>
template<typename Type, bool Optional>
struct Property {
std::conditional_t<Optional, std::optional<Type>, Type> value;
void do_thing() {
if constexpr (Optional) {
if(value)
std::cout << *value << std::endl;
else
std::cout << "null" << std::endl;
} else {
std::cout << value << std::endl;
}
}
};
template<bool Optional>
void Property<std::string, Optional>::do_thing() {
if constexpr (Optional) {
if(value)
std::cout << "\"" << *value << "\"" << std::endl;
else
std::cout << "null" << std::endl;
} else {
std::cout << "\"" << value << "\"" << std::endl;
}
}
int main() {
Property<int, false> prop1{11};
prop1.do_thing();
Property<int, true> prop2;
prop2.do_thing();
Property<std::string, false> prop3{"Test"};
prop3.do_thing();
}
One of the things I need is I need do_thing()
to change in behavior if the Type
is std::string
(or a number of other types I need to specialize).
But, when I try to compile this code, GCC complains about the specialization:
<source>:21:48: error: invalid use of incomplete type 'struct Property<std::__cxx11::basic_string<char>, Optional>'
21 | void Property<std::string, Optional>::do_thing() {
| ^
<source>:6:8: note: declaration of 'struct Property<std::__cxx11::basic_string<char>, Optional>'
6 | struct Property {
| ^~~~~~~~
Execution build compiler returned: 1
What is the proper way to implement this specialization of the function?