1

重複の可能性:
可変個引数テンプレート関数でdecltypeを使用した末尾の戻り型

このコンパイラエラーが発生します:

g++ -std=gnu++0x -I. -O3 -Wall sum.cpp
sum.cpp:7:41: sorry, unimplemented: cannot expand ‘Remaining ...’ into a fixed-length argument list
sum.cpp: In function ‘int main(int, const char**)’:
sum.cpp:29:23: error: no matching function for call to ‘sum(int, int, int)’
sum.cpp:29:23: note: candidate is:
sum.cpp:20:6: note: template<class FirstArg, class ... RemainingArgs> decltype (Sum<FirstArg, RemainingArgs ...>::sum(first, sum::args ...)) sum(const FirstArg&, const RemainingArgs& ...)

このsum.cppの場合:

#include <iostream>
#include <type_traits>

template <typename First, typename... Remaining>
struct Sum {
   static auto sum(const First &arg, const Remaining &... args)
      -> decltype(arg + Sum<Remaining...>::sum(args...))
   {
      return arg + sum(args...);
   }
};

template <typename First>
struct Sum<First>
{
   static First sum(const First &arg) { return arg; }
};

template <typename FirstArg, typename... RemainingArgs>
auto sum(const FirstArg &first, const RemainingArgs &... args)
   -> decltype(Sum<FirstArg, RemainingArgs...>::sum(first, args...))
{
   return Sum<FirstArg, RemainingArgs...>::sum(first, args...);
}

int main(int argc, const char *argv[])
{
   using ::std::cout;
   cout << sum(1, 2, 3) << '\n';

   return 0;
}

この関数を宣言する複数の方法を試しました。これはgcc4.6.1の問題ですか?


編集:::std::common_type私はテンプレートを本当に信頼していないので、これが私が最終的に行ったものです。ただし、まだ問題があります+。左から右ではなく、右から左にバインドされます。これにより、非可換+演算子で問題が発生する可能性があります。ただし、修正するのはそれほど難しくありません。

#include <iostream>
#include <type_traits>
#include <utility>

namespace {
template<class T> typename ::std::add_rvalue_reference<T>::type val();

template<class T> struct id{typedef T type;};

template<class T, class... P> struct sum_type;
template<class T> struct sum_type<T> : id< T > {};
template<class T, class U, class... P> struct sum_type<T,U,P...>
: sum_type< decltype( val<const T&>() + val<const U&>() ), P... > {};
}

template <typename T>
T sum(const T &&arg)
{
   return ::std::forward<const T>(arg);
}

template <typename FirstArg, typename SecondArg, typename... RemainingArgs>
auto sum(const FirstArg &&first, const SecondArg &&second,
         const RemainingArgs &&... args)
   -> typename sum_type<FirstArg, SecondArg, RemainingArgs...>::type
{
   using ::std::forward;

   return forward<const FirstArg>(first) + \
      sum(forward<const SecondArg>(second),
          forward<const RemainingArgs>(args)...);
}

int main(int argc, const char *argv[])
{
   using ::std::cout;
   cout << sum(1, 2, 3.2) << '\n';

   return 0;
}
4

1 に答える 1

6

再帰的に呼び出されている最初の内部sum関数のシグネチャが間違っています。

実行時の可変個引数関数については、次のことを試してください。

#include <type_traits>
#include <utility>

template <typename T> T sum(T && x) { return std::forward<T>(x); }

template <typename T, typename ...Args>
typename std::common_type<T, Args...>::type sum(T && x, Args &&... args)
{
  return std::forward<T>(x) + sum(std::forward<Args>(args)...);
}


int main()
{
  return sum(1,2,3,4);
}
于 2011-11-13T23:04:25.680 に答える