4

私はこのようなクラスを持っていました:

class Test {
public:
    bool bar(int &i, char c) // some arguments are passed by ref, some are by value
    {/*...*/}
    bool foo(/*...*/)
    {}
};

また、bar1 / bar2などを繰り返し呼び出してから、戻り値を何度も確認したくないので、これらを処理するためのマクロと可変個引数のテンプレートを作成しました。

#define help_macro(object, memfn, ...) help_func(#object "." #memfn, \
        object, &decltype(object)::memfn, ##__VA_ARGS__)

template<class T, typename Func, typename... Args>
void help_func(char const * name, T &&object, Func memfn, Args&&... args)
{
    auto ret = (object.*memfn)(forward<Args>(args)...);
    cout<<name<<":\t"
        <<(ret ? "OK" : "Oops")  // maybe I'll throw an exception here  
        <<endl;
}

そして、このように使用します

int i = 0;
Test t;
help_macro(t, bar, i, 'a');

g ++-4.7 / Debianで動作しますが、ICC13.0 / Winはコンパイルを拒否します(非常に奇妙なエラーメッセージ)

main.cpp(37):エラー:タイプ名は許可されていません
help_macro(t、bar、i、'a');
^
main.cpp(37):エラー:「)」
help_macro(t、bar、i、'a');が必要です。
^

ICCのC++11をオンにして、ICC13が可変個引数テンプレートとdecltypeをサポートしていることを確認しました。間違って使用していますか、それともICCの問題ですか。

4

2 に答える 2

2

編集:実際に私の理論をテストするのに苦労したので、私は間違っていたことがわかりました、その文脈でdecltype(t)Teststatic_assert(std::is_same<decltype(t), Test>::value, "not a reference")

したがって、ICC(またはそれが使用するEDGフロントエンド)は、 DR743decltypeによって変更されたnested-name-specifiersでの使用を適切にサポートしていない可能性があります。

ただし、を使用するとICCstd::decay それを受け入れます。したがって、これは便利な回避策です。

オリジナル、間違った、答え

ICCはここにあると思いますが、decltype(object)実際Test&には参照型はメンバーを持つことができないため、形式が正しくありません&decltype(t)::memfn

コードは次のように簡略化できます。

struct Test {
    void foo() {}
};

int main()
{
  Test t;
  auto p = &decltype(t)::foo;
}

どのG++とClangは受け入れますが、ICCは拒否します。正しくはIMHOです。

std::remove_referenceまたはを使用して修正できますstd::decay

#include <type_traits>

// ...

Test t;
auto p = &std::decay<decltype(t)>::type::foo;
于 2013-01-24T14:19:58.980 に答える
0

その理由は、Testクラスに「bar」関数がないためだと思いますが、このコンパイラにアクセスできないため、わかりません。ただし、投稿したエラーメッセージは、「bar」を使用しようとしていることを示しています。

以下はgccとclangの両方で動作します

class Test {
public:
    bool bar1(int &i, char c) // some arguments are passed by ref, some are by value
    {return true;}
    bool bar2(int &i, char c)
    {return true;}
};

#define help_macro(object, memfn, ...) help_func(#object "." #memfn, \
        object, &decltype(object)::memfn, ##__VA_ARGS__)

template<class T, typename Func, typename... Args>
void help_func(char const * name, T &&object, Func memfn, Args&&... args)
{
    auto ret = (object.*memfn)(std::forward<Args>(args)...);
    std::cout<<name<<":\t"
        <<(ret ? "OK" : "Oops")  // maybe I'll throw an exception here
        <<std::endl;
}

int main()
{
    int i = 0;
    Test t;
    //help_macro(t, bar, i, 'a');
    help_macro(t, bar2, i, 'a');
}
于 2013-01-24T09:36:30.760 に答える