簡體   English   中英

強制強類型枚舉參與模板重載解析

[英]force a strongly typed enum to participate in template overload resolution

根據這個問題 - 使用強類型枚舉的模板參數推導- 似乎具有挑戰性 - 如果不是不可能的話 - 讓強類型枚舉器參與重載決議。

如果我們有以下

#include <string>
#include <iostream>

void ExternalFunction(const std::string& tag, int value)
{
    std::cout << tag << " - (int) " << value << std::endl;
}

void ExternalFunction(const std::string& tag, double value)
{
    std::cout << tag << " - (double) " << value << std::endl;
}

void ExternalFunction(const std::string& tag, const std::string& value)
{
    std::cout << tag << " - (string) " << value << std::endl;
}

class Wrapper
{
    public:
        virtual void DoSomething() = 0;
};

template <typename variable_type>
class VariableWrapper : public Wrapper
{
    public:
        VariableWrapper(variable_type variable) : variable(variable) {}
        
        void DoSomething() override
        {
            ExternalFunction("tag", variable);
        }
        
        variable_type& variable;        
};

template <typename enumerator, typename convert_to_string>
class EnumWrapper : public VariableWrapper<enumerator>
{
    public:

        EnumWrapper(enumerator& variable, convert_to_string encoder) : VariableWrapper<enumerator>(variable), encoder(encoder) {}

        void DoSomething() override
        {
            ExternalFunction("tag", encoder(VariableWrapper<enumerator>::variable));
        }
        
        convert_to_string encoder;
};

enum class StronglyTyped
{
    A,
    B,
    C
};

int main()
{
    StronglyTyped e = StronglyTyped::A;
    Wrapper* wrapper = new EnumWrapper(e, [](StronglyTyped S)->std::string{return "Test";});
    wrapper->DoSomething();
}

如果我們嘗試運行它 - http://coliru.stacked-crooked.com/a/d555c4e3300ab05d - 我們會得到錯誤

main.cpp: In instantiation of 'void VariableWrapper<variable_type>::DoSomething() [with variable_type = StronglyTyped]':
main.cpp:31:14:   required from here
main.cpp:33:29: error: no matching function for call to 'ExternalFunction(const char [4], StronglyTyped&)'
   33 |             ExternalFunction("tag", variable);
      |             ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
main.cpp:4:6: note: candidate: 'void ExternalFunction(const string&, int)'
    4 | void ExternalFunction(const std::string& tag, int value)
      |      ^~~~~~~~~~~~~~~~
main.cpp:4:51: note:   no known conversion for argument 2 from 'StronglyTyped' to 'int'
    4 | void ExternalFunction(const std::string& tag, int value)
      |                                               ~~~~^~~~~
main.cpp:9:6: note: candidate: 'void ExternalFunction(const string&, double)'
    9 | void ExternalFunction(const std::string& tag, double value)
      |      ^~~~~~~~~~~~~~~~
main.cpp:9:54: note:   no known conversion for argument 2 from 'StronglyTyped' to 'double'
    9 | void ExternalFunction(const std::string& tag, double value)
      |                                               ~~~~~~~^~~~~
main.cpp:14:6: note: candidate: 'void ExternalFunction(const string&, const string&)'
   14 | void ExternalFunction(const std::string& tag, const std::string& value)
      |      ^~~~~~~~~~~~~~~~
main.cpp:14:66: note:   no known conversion for argument 2 from 'StronglyTyped' to 'const string&' {aka 'const std::__cxx11::basic_string<char>&'}
   14 | void ExternalFunction(const std::string& tag, const std::string& value)
      |                                               ~~~~~~~~~~~~~~~~~~~^~~~~

是否可以讓強類型枚舉器參與重載決議? 我不想刪除強類型 - 這確實刪除了這個問題 - 因為我將不得不在多個枚舉之間使用唯一的名稱

編輯:我已經從問題中刪除了 std::to_string 並相應地更新了代碼,因為它被錯誤地關注。

您編寫的代碼不正確。

好的,所以EnumWrapper<>::DoSomething覆蓋了VariableWrapper<T>::DoSomething 所以它不會通過在任何EnumWrapper對象上直接調用DoSomething來調用。

但這並不意味着VariableWrapper<T>::DoSomething存在 它確實存在,您仍然可以通過合格的調用來調用它。 因此,當您為某個特定T實例化VariableWrapper<T> ,此模板類的成員函數必須有效。

並且VariableWrapper<T>::DoSomething對任何不能用於直接調用ExternalFunction T無效。 這與具體的枚舉無關; 這純粹是關於你如何編寫你的函數。

您應該改為使EnumWrapper不繼承自VariableWrapper 它們都可以從BaseWrapper繼承,但它們沒有相互繼承的業務。 或者,您可以使ExternalFunction本身成為一個模板,該模板可以解決如何為任何給定類型執行任何操作。

暫無
暫無

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

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