4

多くの型に対してオーバーロードされた関数があります。しかし、私の現在の問題はそれによるものです(ここではLWS:lws):

#include <iostream>
#include <string>
#include <sstream>
#include <type_traits>

// First version
template<typename T, class = typename std::enable_if<std::is_fundamental<T>::value>::type> 
std::string f(const T& x)
{
    return std::to_string(x);
}

// Second version
template<typename... T> 
std::string f(const std::tuple<T...>& x)
{
    return std::to_string(sizeof...(T)); // It's just an example here
}

// Third version
template<typename T, class = typename std::enable_if<!std::is_fundamental<T>::value>::type, class = void> 
std::string f(const T& x)
{
    std::ostringstream oss;
    oss<<x;
    return oss.str();
}

// Main
int main(int argc, char* argv[])
{
   std::cout<<f(42)<<std::endl;
   std::cout<<f(std::string("Hello World"))<<std::endl;
   std::cout<<f(std::tuple<int, int, int, int, int, int>(4, 8, 15, 16, 23, 42))<<std::endl;
   return 0;
}

私の問題は、 を呼び出すf()std::tuple、2 番目のバージョンではなく 3 番目のバージョンが実行されることです。

この問題を解決する方法 (解決策は、<<が定義されている型に対してのみ 3 番目のバージョンを許可することですが、その方法がわかりません。これが問題を解決する最善の方法である場合) ?

4

1 に答える 1

5

#include <tuple>唯一の問題は、LWS のエラーに示されている を忘れたことです。これは、正しくコンパイルされる修正バージョンです。2 番目のオーバーロードは、部分順序規則に従ってより特殊化されているため、常に 3 番目のオーバーロードよりも一致します。

SFINAE が存在しない場合にトリガーする関数の存在を確認する方法をまだ知りたい場合は、そのトピック専用の質問でこの回答を確認してください。:)それはあなたが望むものとほぼ一致する例さえ持っています.

于 2012-10-24T19:30:47.957 に答える