1

今天我第一次编译了我的代码库,并使用 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([=]() {

异步看起来像这样:

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

奇怪的是,函子没有在析构函数中声明,不会产生警告。我觉得 gcc 正在生成这些导致冲突的 2 个版本。

4

0 回答 0