3

クラステンプレートのフレンド関数をに詰め込もうとしているところに問題がありますboost::function:

#include <boost/function.hpp>

template <int N>
struct Vec{
   friend
   double dot(Vec, Vec){}
};

template class Vec<2>; //Force multiple instantiations
template class Vec<3>;

int main()
{
    boost::function<double  (Vec<2>, Vec<2>)> func = dot;
    double (*func1)(Vec<2>, Vec<2>) = dot;
}

の 2 行はどちらもmainコンパイルされません。最初のものについて、GCC は不平を言います:

error: conversion from '<unresolved overloaded function type>' to non-scalar type 'boost::function<double(Vec<2>, Vec<2>)>' requested

2行目のエラーは、私にはさらに混乱しているようです:

error: no matches converting function 'dot' to type 'double (*)(struct Vec<2>, struct Vec<2>)'
testtmpl.C:6:15: error: candidates are: double dot(Vec<2>, Vec<2>)
testtmpl.C:6:15: error:                 double dot(Vec<3>, Vec<3>)

一致しない理由がわからないので、ちょっと困っていますdouble dot(Vec<2>, Vec<2>)

ここで何が起こっているかについてのアイデアはありますか?

4

2 に答える 2

5

私の理解では、フレンド関数が他の対応する宣言なしでクラスで定義されている場合、フレンド名は ADL を介してのみ検索できます。
§7.3.1.2/3 は次のように述べています。

フレンドの名前は、その名前空間スコープで一致する宣言が提供されるまで、単純な名前検索では見つかりません。

ここ
double dot(Vec<2>, Vec<2>);の よう に対応する関数宣言を追加することで、コードをコンパイルできるようになり ます。

于 2011-07-15T05:32:32.477 に答える
0

これはうまくいきます:

template <int N> struct Vec;

template <int K> double dot(Vec<K>, Vec<K>) { return 0; }

template <int N>
struct Vec
{
  friend double dot<>(Vec<N>, Vec<N>);
};

GCC 4.6.1 では、実際に非常に役立つ警告が表示されました。

warning: friend declaration ‘double dot(Vec<N>, Vec<N>)’ declares a non-template function [-Wnon-template-friend]
note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)
于 2011-07-14T21:21:39.640 に答える