HappyCactus
HappyCactus

Reputation: 2014

Reordering of an overloaded Template function

I have a class InsertStatement that uses an external function bind:

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;
   }
   ...
};

The reason for using an external function is to be able to override it and support the use of other types in the InsertStatement class. For example, if I want to use it with StrongType<T>, I can do this:

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());
}
}

The problem is that I need to include the StrongType.h before InsertStatement.h, otherwise the compiler is unable to resolve correctly the function call.

Though I can explain it intuitively, the question is, how can I avoid this problem? I don't want to #include "StrongType.h" from InsertStatement.h because StrongType is an external class not directly related to this library, and because this will indeed occurs with any new type, and I want to keep the class flexible enough.

I'm using different compilers (gcc, clang and MSVC), c++14 (c++17 or later is not an option for the moment).

  1. How can I avoid this kind of "header ordering" problems?
  2. What is the best approach to let a Templated class to be expanded with other types, whose details are unknown to the class?

Upvotes: 2

Views: 80

Answers (1)

Jarod42
Jarod42

Reputation: 217810

You might rely on ADL and have bind in same namespace than StrongType.
(you need to not use qualified call):

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

Upvotes: 1

Related Questions