VS2017でC++ 17サポートを有効にしています。C++ 17 texleでconstexpr()を使用する場合
サポートされている特定の型が提供されると型を変換する "Transformer"クラスを作成しようとします。それ以外の場合はそのまま変数を返します。目的は、すべての変数タイプをトランスに渡し、どの変数タイプをトランスフォームにするかを隠すことです。この方法では、発信者はすべてを変換しようとすることができ、変換が必要かどうかについて心配する必要はなく、変圧器は知っているでしょう。
(元から編集)より完全な例:
class MyPoint
{
public:
int x = 0;
};
class NotMyPoint
{
public:
int x = 50;
};
template <typename T>
class ITransform
{
public:
virtual ~ITransform() {};
virtual T InTransform(const T &in) const = 0;
virtual T OutTransform(const T &out) const = 0;
//Check if the argument type is the same as this class type
template <typename X>
constexpr bool CanTransform() const
{
return std::is_same<X, T>::value;
}
};
class MyTransformer :
public ITransform<MyPoint>
{
public:
MyTransformer() = default;
virtual MyPoint InTransform(const MyPoint &in) const override
{
auto newPt = in;
newPt.x += 100;
return newPt;
}
virtual MyPoint OutTransform(const MyPoint &in) const override
{
auto newPt = in;
newPt.x -= 100;
return newPt;
}
};
template <class... TRANSFORMERS>
struct VariadicTransformer
{
constexpr VariadicTransformer() = default;
/** \brief parse using validateParse but catch throw */
template <typename T>
inline T Transform(const T& in)
{
return TransformImpl<sizeof...(TRANSFORMERS)-1, T>(in);
}
private:
/// last attempt to find matching transformer at I==0, if it fails return the original value
template<std::size_t I = 0, typename T>
inline typename std::enable_if<I == 0, T>::type TransformImpl(const T &in) const
{
if (std::get<I>(transformers).CanTransform<T>())
return std::get<I>(transformers).InTransform(in);
else
return in;
}
/// attempt to find transformer for this type
template<std::size_t I = 0, typename T>
inline typename std::enable_if < I != 0, T>::type TransformImpl(const T &in) const
{
if (std::get<I>(transformers).CanTransform<T>())
return std::get<I>(transformers).InTransform(in);
else
return TransformImpl<I - 1, T>(in);
}
std::tuple<const TRANSFORMERS...> transformers;
};
//Example usage
VariadicTransformer<MyTransformer, MyTransformer> varTrans;
MyPoint myPoint;
NotMyPoint notMyPoint;
std::cout << myPoint.x << std::endl;
myPoint = varTrans.Transform(myPoint);
std::cout << myPoint.x << std::endl;
std::cout << notMyPoint.x << std::endl;
notMyPoint = varTrans.Transform<NotMyPoint>(notMyPoint);
std::cout << notMyPoint.x << std::endl;
return 0;
私の問題は、このラインとしています:
if constexpr(std::get<I>(transformers).CanTransform<T>())
これは、コンパイルし、次のエラーを提供していません。
エラーC2131:式が定数に評価されませんでした
注:failuべきconstexprの、のstd :: <#>(STD ::タプル)を取得する必要があります「この」
CanTransform機能の参照使用:その寿命外変数の読み取りによって
ノートを引き起こした再私はこの行についての苦情が何であるか不明です。
また、現在のタイプを変換することができないトランスを呼び出そうとするのを避けるためにconstexprが必要な場合は、このケースをフォールバックして元に戻します。
このエラーの原因とは何かに関するアドバイスや、別のデザインを試すことができますか?
'のstd ::取得(this->変圧器).CanTransform()' '→のstd ::を(this->変圧器)を取得.TEMPLATE CanTransform ( ) ' –
Constructor
' return constexpr(...); 'は有効ではありませんC++。 – chris
@chrisこれはVisual C++の拡張機能かバグですか?私はそのような建設に関する情報をすばやく見つけることはできません。 – Constructor