這里是初學者的問題,所以我有以下代碼
foo.h
enum class Fruit : uint16_t {
Apple = 8019U,
Orange = 8020U,
Banana = 8021U,
Cactus = 8022U
};
class Foo {
public:
template<typename T> void SetValue(unsigned int location, const T& value);
template<typename T> void SetValue(unsigned int location, const T* value_ptr);
template<typename T> void SetValue(Fruit fruit, const T& value);
template<typename T> void SetValue(Fruit fruit, const T* value_ptr);
}
foo.cpp
template<typename T>
void Foo::SetValue(unsigned int location, const T& value) {
std::cout << value << std::endl;
}
template<typename T>
void Foo::SetValue(unsigned int location, const T* value_ptr) {
std::cout << (*value_ptr) << std::endl;
}
template<typename T>
void Foo::SetValue(Fruit fruit, const T& value) {
SetValue<T>(static_cast<unsigned int>(fruit), value);
}
template<typename T>
void Foo::SetValue(Fruit fruit, const T* value_ptr) {
SetValue<T>(static_cast<unsigned int>(fruit), value_ptr);
}
#define INSTANTIATE_TEMPLATE(T) \
template void Foo::SetValue<T>(unsigned int location, const T& value); \
template void Foo::SetValue<T>(unsigned int location, const T* value_ptr); \
template void Foo::SetValue<T>(Fruit fruit, const T& value); \
template void Foo::SetValue<T>(Fruit fruit, const T* value_ptr);
INSTANTIATE_TEMPLATE(int)
INSTANTIATE_TEMPLATE(uint)
INSTANTIATE_TEMPLATE(bool)
INSTANTIATE_TEMPLATE(float)
INSTANTIATE_TEMPLATE(vec2)
INSTANTIATE_TEMPLATE(vec3)
INSTANTIATE_TEMPLATE(vec4)
INSTANTIATE_TEMPLATE(mat2)
INSTANTIATE_TEMPLATE(mat3)
INSTANTIATE_TEMPLATE(mat4)
...
#undef INSTANTIATE_TEMPLATE
main.cpp
int main() {
Foo foo;
float bar[7] { 0.0f, 0.15f, 0.3f, 0.45f, 0.6f, 0.75f, 0.9f };
float baz = 12.5f;
foo.SetValue(Fruit::Orange, 1.05); // calling SetValue<double>(Fruit fruit, const double& value)
foo.SetValue(Fruit::Apple, bar 3); // calling SetValue<float*>(Fruit fruit, float *const& value)
foo.SetValue(Fruit::Cactus, &baz); // calling SetValue<float*>(Fruit fruit, float *const& value)
}
在最后 2 個電話中,雖然我真的打算打電話
SetValue<float>(Fruit fruit, const float* value_ptr)
實際上被稱為的是
SetValue<float*>(Fruit fruit, float *const& value)
我知道這是模棱兩可的,因為 VS Intellisense 無法SetValue<T>在被覆寫的函式體中突出顯示顏色,所以我嘗試改寫foo.SetValue<float>(Fruit::Cactus, &baz),現在編譯器解釋T為float而不是float*,但我想知道這是否是一個可怕的設計...... ...有沒有更好的方法不需要我明確指定的型別T?我怎樣才能完全消除歧義?
uj5u.com熱心網友回復:
我知道這是模棱兩可的
它不是。
const T& value是比const T* valuefor更好的匹配float*。前者是完全匹配,而后者需要進行限定轉換。
您可能會洗掉constfor 指標:
template<typename T> void SetValue(Fruit fruit, T* value_ptr);
演示
uj5u.com熱心網友回復:
如果您確實想使用 SFINAE。
template<typename T, std::enable_if_t<!std::is_pointer<T>::value, bool> = false>
// no difference between = true or = false
void SetValue(unsigned int location, const T& value) {
std::cout << value << std::endl;
}
template<typename T>
void SetValue(unsigned int location, const T* value_ptr) {
std::cout << (*value_ptr) << std::endl;
}
只需使用它來替換上述 2 個功能(其中 cout 的功能)。我不認為第四個函式(Fruit fruit, const T* value_ptr)是必要的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/410975.html
標籤:
下一篇:如何擴展無值引數包
