模板结构自身违反ODR

时间:2015-10-10 17:52:39

标签: c++ templates gcc one-definition-rule

今天我第一次编译了我的代码库,并使用gcc 5.1启用了链接时优化,我收到了奇怪的ODR警告:

Functor.h:67:8: warning: type 'struct Func' violates one definition rule [-Wodr]
    class Func : public FuncBase
Functor.h:67:8: note: a different type is defined in another translation unit
    class Func : public FuncBase

代码如下:

template<typename R, typename... Args>
class Functor
{
    class FuncBase : NonCopyable
    {
        public:
            FuncBase() {
            }
            virtual ~FuncBase() {
            }
            virtual R apply(Args...) = 0;
    };
    template<typename T>
    class Func : public FuncBase
    {
        public:
            Func(const T &t) : f(t) {
            }
            virtual ~Func() {
            }
            virtual R apply(Args... args) override {
                return f(args...);
            }
        private:
            T f;
    };
    /* ... */

    std::shared_ptr<FuncBase> func;
    public:
    template<typename T>
    Functor(const T &t) : func(new Func<T>(t)) {
    }


};

如您所见,Func与自身发生冲突。

gcc如何在模板类中找到ODR问题? 我完全不了解ODR,但我觉得应该有'多次声明'错误。

注意:成员f似乎是问题的根源:

Functor.h:81:6: note: a field of same name but different type is defined in another translation unit
T f;

注2: 问题似乎只有在我在析构函数中构造一个Functor时才出现:

UniformBuffer.h:40:26: note: type name 'DynamicBuffer::Data::~Data(int)::{lambda()#1}' should match type name 'DynamicBuffer::Data::~Data()::{lambda()#1}'
  Async([=]() {
UniformBuffer.h:40:26: note: the incompatible type is defined here
  Async([=]() {

Async看起来像这样:

void Async(const Functor<void> &f) {
   // ....
}

很奇怪,仿函数没有在析构函数中声明,也没有生成警告。我觉得gcc正在产生2个版本,导致冲突。

0 个答案:

没有答案