1

bbb の行がコメント アウトされていないが、その前の行がコメント アウトされていない場合に、次のコードがコンパイルされて期待どおりに動作する理由を知りたいのですが、aaa でマークされた行がコメント アウトされておらず、bbb の行がコメント アウトされていない場合は失敗します。は:

#include <iostream>
#include <string>
using String = std::string;
struct Person {
    String m_name;
    explicit Person(String const &name): m_name(name) {}
    operator String() const { return "\"" + m_name + "\""; }
};

template<class T> bool isEqual(
T const& a,
//T const& // does NOT compile // aaa
decltype(a) // DOES compile    // bbb
b){ return a == b; }

int main()
{
    String const  plain("plain");
    Person const jb("James");
    bool b = isEqual(plain, jb);
    std::cout << "isEqual(plain, person) is " << ( b ? "true" : "false" ) << "\n";
}
4

1 に答える 1

3

あなたがするとき:

template<class T> 
bool isEqual(T const& a, T const& b)

sは異なる型 ( forとfor )Tとして推測します。できるのは 1 つの型だけなので、推論が失敗するのはそのためです。StringaPersonbT

ただし、次の場合:

template<class T> 
bool isEqual(T const& a, decltype(a) b)

パラメータ/引数のペアを 1 つだけ推定する必要があります。Tとして推定されString、(変換関数を介して)に変換Personできるため、これは問題なく機能します。Stringoperator String()

identityこれは、単純に 1 つのパラメーターを非推定コンテキストに強制するトリックに似ています。

template <typename T>
struct identity { using type = T; };

template <typename T>
bool isEqual(T const& a, typename identity<T>::type const& b);

ここでも、型演繹が行われるペアは 1 つしかなく、Tは - と推論されるStringため、 の型bString const&です。

于 2015-08-14T18:18:57.333 に答える