簡體   English   中英

模板 function 重載歧義

[英]template function overloading ambiguity

這里是初學者的問題,所以我有以下代碼

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 無法在被覆蓋的 function 主體中為SetValue<T>着色,所以我嘗試改寫foo.SetValue<float>(Fruit::Cactus, &baz) ,現在編譯器將T解釋為float而不是float* ,但我想知道這是否是一個可怕的設計......有沒有更好的方法不需要我明確指定T的類型? 我怎樣才能完全消除歧義?

我知道這是模棱兩可的

它不是。

const T& valuefloat*const T* value更好。 前者是完全匹配,而后者需要進行限定轉換

您可以刪除指針的const

template<typename T> void SetValue(Fruit fruit, T* value_ptr);

演示

如果您確實想使用 SFINAE。

 template<typename T, std::enable_if_t<!std::is_pointer<T>::value, bool> = false> 
// I don't really know if there is a 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 )是必要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM