模板构造函数

时间:2016-02-11 19:23:24

标签: c++ variadic-templates

尝试为异常编写模板化的构造函数类,因此我可以在抛出异常时放入变量长度参数,并且像这样:

namespace miniReader{

    namespace Exception{

        template<typename deriverEx, typename baseType>
        class Exception : public baseType{
            std::string errorClass;
            mutable std::string exStrMsg;
        protected:
            static  std::stringstream exMsg;
            std::string whatMessage;
           // Exception(const Exception& other): baseType(""){}

            const char* what() const noexcept{
                if(exStrMsg.empty()){
                    exStrMsg = exMsg.str();
                }
                exMsg.str("");
              return exStrMsg.c_str();
            }

            ~Exception() noexcept {
            }
        public:
            Exception(): baseType("") {
            }
        };

        class miniRuntimeException : public Exception<miniRuntimeException, std::runtime_error>{
        public:
            miniRuntimeException(): Exception() {}

            template<typename T, typename...Args>
            miniRuntimeException(T first, Args...arg): Exception(){
                LOG(first, this);
                exMsg << first << " ";
                miniRuntimeException(arg...);
            }
        };

    template<typename deriverEx, typename baseType>
    std::stringstream  Exception<deriverEx, baseType>::exMsg;

    }
}

现在我可以像这样编写抛出异常:

 miniRuntimeException(__FILE__, __LINE__, "Failed opening file", "Runtime Exception")

我故意将exMsg设为静态,因为在其他情况下我可以获取所有模板参数。所以我的问题是Exception类中的exMsg是静态的,所以当调用派生类构造函数(可变参数模板)时,读参数是正确的。我找不到一种方法使它非静态,因为exMsg只能获得一个模板参数。有没有办法做到这一点?下一个问题是当我的模板构造函数被调用时,为每个参数创建新对象(这是正确的吗?)以及在这种情况下我如何在这些对象之间传递信息,比如更新exMsg以便它在最终对象中完成?

1 个答案:

答案 0 :(得分:0)

我想我理解这个问题(读了3遍之后)。我建议用以下代码替换构造函数链(为了清楚起见,省略了继承):

class miniException {
    std::stringstream msg;
public:
    template<class... ARGS> miniException(ARGS... args) {
       populate_msg(args...);
    }
private:
    template<class T, class... ARGS> void populate_msg(T t, ARGS... args) {
        msg << t << " ";
        populate_msg(args...);
    }
};
void populate_msg() { }

P.S。实际上,您可能希望通过const引用而不是值来接受参数。