专门为模板化(犰狳)类的模板化功能

时间:2014-08-08 12:17:57

标签: c++ templates overloading armadillo

我正在尝试组建一个非常简单的日志记录类,它专门处理某些类型,特别是向量。我希望在使用<<运算符时有默认行为,但在某些情况下会修改它。设置是:

class LoggerStream
{
    template <typename ArgType>
    LoggerStream & operator<< (const ArgType &arg)
    {
        // Standard logging logic
        return *this;
    }

    template <typename DataType>
    LoggerStream & operator<< (const std::vector<DataType> &arg)
    {
        // Specialised logging logic
        return *this;
    }

    template <typename DataType>
    LoggerStream & operator<< (const arma::Col<DataType> &arg)
    {
        // Specialised logging logic
        return *this;
    }

    LoggerStream & operator<< (const double &arg)
    {
        // Specialised logging logic
        return *this;
    }

    // Other stuff...
};

double案例工作正常。问题是,对于矢量类型的子类,通用模板似乎优先,更具体的模板被忽略。

由于所有三个模板化案例只有一个通用模板参数,我猜测矢量案例不被认为是最专业的,但如果它被认为是不明确的,我会期望编译器错误。 (它编译得很好。)那么我怎样才能指出一个专业化但仍然概括了向量元素的类型?提前致谢。

我想这与Col类如何实现的一些细节有关。我也使用(和别名)arma::Col<T>::fixed<N>,但为此编写特定的重载似乎没有帮助。欢迎任何想法。

2 个答案:

答案 0 :(得分:0)

我无法重现它。这段代码可以正常工作:

#include <iostream>
#include <vector>

using namespace std;

class LoggerStream
{
public:
    template <typename ArgType>
    LoggerStream &operator<< (const ArgType &arg)
    {
        // Standard logging logic
        cout << "In general" << endl;
        return *this;
    }

    template <typename DataType>
    LoggerStream &operator<< (const std::vector<DataType> &arg)
    {
        // Specialised logging logic
        cout << "In vector" << endl;

        return *this;
    }

};

int main()
{
    LoggerStream foo;
    vector<int> v;
    foo << v; // calling the vector specialization
}

答案 1 :(得分:0)

我正在回答我自己的问题,不是因为我有一个决议(但是),而是在进一步调查之后澄清问题。事实上,这似乎并不是arma::Col所特有的;相反,当参数是子类类型时,问题似乎是在更具体的重载的优先级。一个不使用Armadillo就可以显示问题的简单例子是

#include <iostream>
#include <vector>

using namespace std;

template <typename DataType>
class MyVector : public std::vector<DataType> {};

class LoggerStream
{
public:
    template <typename ArgType>
    LoggerStream &operator<< (const ArgType &arg)
    {
        cout << "In general" << endl;
        return *this;
    }

    template <typename DataType>
    LoggerStream &operator<< (const std::vector<DataType> &arg)
    {
        cout << "In vector" << endl;
        return *this;
    }
};

int main()
{
    LoggerStream foo;
    std::vector<float> v;
    foo << v;  // Prints "In vector", as expected
    MyVector<float> w;
    foo << w;  // Prints "In general" (but only if the general case exists)
}

因此,使用子类MyVector会产生对常规函数的调用,而不是专用函数。但是,如果第一个版本被注释掉,则两个调用都会生成“向量”。因此,出于某种原因,两者都被认为是合适的,但一般的功能是首选。

我还不知道如何在没有为各个子类案例明确写出特定重载的负载的情况下阻止这种情况发生......