g++ での volatile の扱いが微妙に変

スレッドセーフの定義では「基本的に複数のスレッドからアクセスするオブジェクトには volatile 修飾しません?」などとコメントしつつも、その実、ほぼ全ての自作クラスは volatile 修飾に全然対応してなかったよなぁと、反省し、volatile 修飾対応を始めた矢先に g++ での volatile の扱いが微妙に変なことを発見しました。というのも以下のコードが g++(3.4.4) でのみコンパイルエラーになります。

#include <stddef.h>

typedef unsigned char byte_type;

class const_binary_ptr
{
public:
    const_binary_ptr(const volatile const_binary_ptr &) { }
    const_binary_ptr(const void *) { }
    operator const void * () const
    {
        return NULL;
    }
};

class simple_buffer
{
    const_binary_ptr  data_ptr;
public:
    const_binary_ptr data() const
    {
        return data_ptr;
    }
    void assign(const simple_buffer &a)
    {
        assign(a.data()); // ←ここでエラーになる。
    }
    void assign(const const_binary_ptr &) { }
};

const_binary_ptr の一つ目のコンストラクタがミソで、ここで引数に volatile 修飾がなければエラーにならないのですが、volatile 修飾をつけると const_binary_ptr のどちらのコンストラクタを使っていいのか曖昧だという旨のエラーが発生してしまいます。volatile 修飾というのは所謂 cv 修飾の v であり、const 修飾と同じように機能しなければならず、この場面では volatile 修飾があるからといってこのようなエラーがでてはいけません。

ちなみに今、手元の g++ は 3.4 しかなく他のバージョンでは確認しておりません。また他のコンパイラ(Visual C++ 6.0/7.1/8.0, Borland C++ 5.2/5.51/5.64/5.9, Intel C++ 7.0, OpenWatcom 1.5, Metrowerks 2.4/3.0.1, Digital Mars 8.42n)では一切このようなコンパイルエラーは見られませんでした。