operator*=
ve operator*
aşırı yüklü çoğaltma ile basit bir Wrapper
sınıfı düşünün. "Eski stil" operatör aşırı yüklemesi için, operator*=
açısından operator*
tanımlanabilir, ve Boost.Operators gibi kütüphaneler bile vardır ve @DanielFrey tarafından sizin için en uygun olan, df.operators modern kazanımı vardır. Bununla birlikte, yeni C++ 11 constexpr
'u kullanarak derleme zamanı hesaplamaları için, bu kolaylık ortadan kalkar. İkincisi onun (örtük) sol argüman değiştirir çünkü constexpr operator*
operator*=
diyemezsin. Dahası, orada no overloading on constexpr, yani bir aşırı yük çözünürlük belirsizlik mevcut operator*
sonuçlarına fazladan constexpr operator*
ekledi.Constexpr operatör aşırı yükleme yapmak için yönergeler?
Benim şu anki yaklaşımdır:
#include <iostream>
struct Wrap
{
int value;
Wrap& operator*=(Wrap const& rhs)
{ value *= rhs.value; return *this; }
// need to comment this function because of overloading ambiguity with the constexpr version
// friend Wrap operator*(Wrap const& lhs, Wrap const& rhs)
// { return Wrap { lhs } *= rhs; }
friend constexpr Wrap operator*(Wrap const& lhs, Wrap const& rhs)
{ return { lhs.value * rhs.value }; }
};
constexpr Wrap factorial(int n)
{
return n? factorial(n - 1) * Wrap { n } : Wrap { 1 };
}
// want to be able to statically initialize these arrays
struct Hold
{
static constexpr Wrap Int[] = { factorial(0), factorial(1), factorial(2), factorial(3) };
};
int main()
{
std::cout << Hold::Int[3].value << "\n"; // 6
auto w = Wrap { 2 };
w *= Wrap { 3 };
std::cout << w.value << "\n"; // 6
}
Live output here. Bu Benim sorunlar şunlardır:
- hem
operator*=
veoperator*
yılında çarpma mantığının çoğaltılması, yerineoperator*
dolayısıylaoperator*=
- cinsinden ifade ediliyor, Boost.Operators artık pek yazmak için klişe azaltmak için çalışır diğer aritmetik operatörler
Soru: bir çalışma zamanı operator*=
ve karışık çalışma zamanı hem de sahip olan, bu önerilen C++ 11 yolu/derleme zamanı 01.237.? C++ 14 burada herhangi bir şeyi değiştirir. mantık çoğaltmayı azaltmak?
GÜNCELLEME: @AndyProwl tarafından cevap deyimsel olarak kabul etmiş, ancak @DyP önerisi gereğince, içinde olduğu C++ 11 tek fazladan atama ve karşı-sezgisel tarzı pahasına mantık tekrarını azaltabilir
// define operator*= in terms of operator*
Wrap& operator*=(Wrap const& rhs)
{ *this = *this * rhs; return *this; }
o 'constexpr' olabilir eğer bir 'normal' aşırı için ne faydası var? IIRC 'constexpr' incelikle olmayan 'constexpr' bağlamda execution_ _runtime için düşer. – sehe
@se, bir constexpr operatörüne sahip olamazsınız * = ', ve' constexpr operatörü * 'bunu çağıramaz ve bunun yerine alanları ayıklama mantığını çoğaltmanız gerekir. – TemplateRex
Ah, asıl sorunuzu görmeye başladım. O var *** değil *** (onları gerek yok!) Ama olmayan 'constexpr' aşırı yükleri olması konusunda oldukça '* =' 'constexpr' olamaz çünkü kod paylaşmak mümkün değil varlık hakkında.İyi bir şey, zaten iyi niyetle + 1ediyorum :) – sehe