【问题标题】:how to force compiler to use the correct overloaded method in c++ for a templated class如何强制编译器在 C++ 中为模板类使用正确的重载方法
【发布时间】:2025-12-24 01:30:11
【问题描述】:

我想为我正在为一个 c++ 类工作的斐波那契类创建下一个元素方法,但我希望它适用于字符串和长整数,而不必编写两个单独的方法。

我写了一个模板函数,但编译器无法检查 if 语句,所以它总是说可以在字符串类型上使用 std::to_string(),编译器会失败。

所以我不得不做出两种方法来处理string和longs

        template <typename T>
        void fib<T>::next_ele(){
            if(typeid(a_) == typeid(long(0))){
                std::cout<<typeid(a_).name();
                T nextp = a_ + b_;
                seq_+=",";
                seq_+=std::to_string(nextp);
                a_ = b_;
                b_ = nextp;     
            }
            else{
                T nexte = b_ + a_;
                seq_+=",";
                seq_+=nexte;
                a_ = b_;
                b_ = nexte;
            }

        }

主程序

        #include "fibclass.h"
        #include <typeinfo>
        #include <string>
        using std::string;
        #include <iostream>
        using std::cout; using std::endl;

        int main(){

            cus::fib<long> a;
            cout<<a<<endl;
            for(int i = 1; i<=5; i++){
                a.next_ele(4);
            }

            cout<<a<<endl;
            cus::fib<string> b("a","b");
            for(int i = 1; i<=6; i++){
                b.next_ele("p");
        }
            cout<<b;
        }

使用两种不同方法的标题基本上可以解决

        #ifndef FIBH
        #define FIBH

        #include <string>
        using std::string;
        #include <typeinfo>
        #include <iostream>
        namespace cus{
            template <typename T>
            class fib{
                private:

                public:
                    string seq_;
                    T a_;
                    T b_;
                    fib() : seq_("0,1") , a_(long(0)), b_(long(1)){};
                    fib(T a, T b) : seq_(""), a_(a), b_(b) {};
                    void next_ele(long);
                    void next_ele(string);
                    friend std::ostream& operator<<(std::ostream& out,fib& f){
                out<<f.seq_;
                return out;
            };


            };

        template <typename T>
        void fib<T>::next_ele(long b){
            long nextp = a_ + b_;
            seq_+=",";
            seq_+=std::to_string(nextp);
            a_ = b_;
            b_ = nextp; 
        }   
        template <typename T>
        void fib<T>::next_ele(string a){
                string nexte = b_ + a_;
                if (!(seq_.empty()))
                    seq_+=",";
                seq_+=nexte;
                a_ = b_;
                b_ = nexte;
            }

        }

        #endif

【问题讨论】:

  • 谷歌搜索“模板专业化”。无论如何,您最终都会编写单独的方法。
  • 好的,我将如何格式化方法以识别是调用长方法还是字符串方法,谢谢您的帮助
  • 我想我有一个适合你的解决方案,但你是否理解声明 T nexte = b_ + a_; 只会将字符串连接在一起而不是真正“添加”任何东西?结果将是一串不断增加的零和一。 (例如1010110101101101)而不是任何代表斐波那契序列的东西。如果这就是你想要的,我会分享我的解决方案。

标签: c++ methods


【解决方案1】:

是的:问题出在std::to_string() 函数上。 long 存在,但 std::string 不存在。

即使Tstd::stringstd::to_string() 也已编译(如果该部分代码未执行)。

如果你真的想要一个方法(但是......专业化有什么问题?)......我想你可以使用std::ostringstream,它适用于整数和字符串,而不是@ 987654328@;像

template <typename T>
   void fib<T>::next_ele(){

      std::cout << "typename is [" << typeid(a_).name() << "]\n";

      std::ostringstream  oss;

      T nextpe = ( typeid(a_) == typeid(long(0)) ? a_ + b_ : b_ + a_ );

      oss << ',' << nextpe;

      seq_ += oss.str();
      a_    = b_;
      b_    = nextpe;
   }

p.s.1:如果您使用std::ostringstream,请记住包含&lt;sstream&gt;

p.s.2:对不起我的英语不好。

【讨论】:

  • 谢谢!这就是我一直在寻找的答案