我有一个使用外部函数InsertStatementbind类:

namespace sqlite {

template <typename T>
inline void bind(SQLiteStatement &statement, size_t idx, const T &value) {
    statement.bind(idx, value);
}

template<typename ...FIELDS>
class InsertStatement {

   ...
   template <typename T>
   bool bindValue(int idx, const T& t) {
       sqlite::bind(*statement, idx+1, t);
       return true;
   }
   ...
};

使用外部函数的原因是能够覆盖它并支持在InsertStatement类中使用其他类型。例如,如果要与StrongType<T>一起使用,可以执行以下操作:
template <typename T, typename TAG>
class StrongType {
private:
    T value;
public:
    StrongType (T&& v)
            : value(std::forward<T>(v)) {

    }

    T toValue() const
    {
        return value;
    }
};

namespace sqlite {

template <typename T, typename TAG>
inline void bind (SQLiteStatement &statement, size_t s, const StrongType<T,TAG> &strongType) {
    statement.bind(s, strongType.toValue());
}
}

问题是我需要在StrongType.h之前包括InsertStatement.h,否则编译器将无法正确解析函数调用。

尽管我可以直观地解释它,但问题是,如何避免这个问题?我不想从#include "StrongType.h"中使用InsertStatement.h,因为StrongType是与该库没有直接关系的外部类,并且因为在任何新类型中确实会发生这种情况,并且我想使该类足够灵活。

我正在使用不同的编译器(gcc,clang和MSVC),c++ 14(暂时不选择c++ 17或更高版本)。
  • 如何避免这种“标题排序”问题?
  • 什么是让Templated类扩展其类型未知的其他类型的最佳方法?
  • 最佳答案

    您可能依赖ADL并将bindStrongType放在同一命名空间中。
    (您无需使用合格的通话):

    template <typename T>
    bool bindValue(int idx, const T& t) {
        using sqlite::bind;
        bind(*statement, idx+1, t);
        return true;
    }
    

    09-18 08:59