变量参数函数,如何使其类型安全且更有意义?

eas*_*gel 7 c++

我是C++的新手,我的第一语言是中文,所以我的英语单词可能是无意义的,先说对不起.我知道有一种方法可以编写一个带有可变参数的函数,每个调用的数字或类型可能不同,我们可以使用va_list,va_start和va_end的宏.但众所周知,这是C风格.当我们使用宏时,我们将失去类型安全和自动推理的好处,然后我尝试使用C++模板.我的工作如下:


#include<iostream>
#include<vector>
#include<boost/any.hpp>

struct Argument
{
    typedef boost::bad_any_cast bad_cast;

    template<typename Type>
    Argument& operator,(const Type& v)
    {
        boost::any a(v);
        _args.push_back(a);
        return *this;
    }

    size_t size() const
    {
        return _args.size();
    }

    template<typename Type>
    Type value(size_t n) const
    {
        return boost::any_cast<Type>(_args[n]);
    }

    template<typename Type>
    const Type* piont(size_t n) const
    {
        return boost::any_cast<Type>(&_args[n]);
    }
private:
    std::vector<boost::any> _args;
};

int sum(const Argument& arg)
{
    int sum=0;
    for(size_t s=0; s<arg.size(); ++s)
    {
        sum += arg.value<int>(s);
    }

    return sum;
}

int main()
{
    std::cout << sum((Argument(), 1, 3, 4, 5)) << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我觉得这很难看,我想有办法做得更好吗?谢谢,抱歉语言错误.

P S*_*ved 3

你可以这样做:

template <typename T>
class sum{
    T value;
    public:
    sum ()
            : value() {};
    // Add one argument
    sum<T>& operator<<(T const& x)
            { value += x; return *this; }
    // to get funal value
    operator T()
            { return value;}
    // need another type that's handled differently?  Sure!
    sum<T>& operator<<(double const& x)
            { value += 100*int(x); return *this; }
};

#include <iostream>

int main()
{
    std::cout << (sum<int>() << 5 << 1 << 1.5 << 19) << "\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这种技术(运算符重载和类流函数类)可以解决可变参数的不同问题,而不仅仅是这个问题。例如:

create_window() << window::caption - "Hey" << window::width - 5;
     // height of the window and its other parameters are not set here and use default values
Run Code Online (Sandbox Code Playgroud)

  • 我不建议为此使用转换函数。即使您*不*重载 double 的运算符&lt;&lt;,您仍然会得到 `sum&lt;int&gt;() &lt;&lt; 2L` 的歧义,因为它与 int 类型的内置移位运算符冲突(这些情况非常微妙)。我将提供一个返回总和的非成员 `get` 函数(请参阅“非成员 get() 习惯用法”),并且通常避免转换函数。 (2认同)