diff --git a/Framework/API/src/CompositeFunction.cpp b/Framework/API/src/CompositeFunction.cpp
index 48d27693fe5d84b735ce9aee88f14bb8ae8f6f1c..e1b589627bf6e5ed22902adb86d4f5313b5e3313 100644
--- a/Framework/API/src/CompositeFunction.cpp
+++ b/Framework/API/src/CompositeFunction.cpp
@@ -508,8 +508,9 @@ void CompositeFunction::replaceFunction(size_t i, IFunction_sptr f) {
     } else if (np_new > 0) // it could happen if the old function is an empty
                            // CompositeFunction
     {
+      using std::placeholders::_1;
       itFun = std::find_if(m_IFunction.begin(), m_IFunction.end(),
-                           std::bind2nd(std::greater<size_t>(), i));
+                           std::bind(std::greater<size_t>(), _1, i));
       m_IFunction.insert(itFun, np_new, i);
     }
   }
diff --git a/Framework/Algorithms/src/Bin2DPowderDiffraction.cpp b/Framework/Algorithms/src/Bin2DPowderDiffraction.cpp
index a8c2373d380636b2d0c3c8d6bd3967a7b0f73756..2dc486eb16ef673470f0eefb72c4216f3a63ad04 100644
--- a/Framework/Algorithms/src/Bin2DPowderDiffraction.cpp
+++ b/Framework/Algorithms/src/Bin2DPowderDiffraction.cpp
@@ -377,11 +377,12 @@ void Bin2DPowderDiffraction::normalizeToBinArea(MatrixWorkspace_sptr outWS) {
     // divide by the xBinWidth
     outWS->convertToFrequencies(idx);
     auto &freqs = outWS->mutableY(idx);
+    using std::placeholders::_1;
     std::transform(freqs.begin(), freqs.end(), freqs.begin(),
-                   std::bind1st(std::multiplies<double>(), factor));
+                   std::bind(std::multiplies<double>(), factor, _1));
     auto &errors = outWS->mutableE(idx);
     std::transform(errors.begin(), errors.end(), errors.begin(),
-                   std::bind1st(std::multiplies<double>(), factor));
+                   std::bind(std::multiplies<double>(), factor, _1));
   }
 }
 
diff --git a/Framework/Algorithms/src/CalculateTransmissionBeamSpreader.cpp b/Framework/Algorithms/src/CalculateTransmissionBeamSpreader.cpp
index 4144cd7109ec8bc8799c5b8d9919cf55e3eb1689..d2dc527332185e9708d466a59b80b032916627e7 100644
--- a/Framework/Algorithms/src/CalculateTransmissionBeamSpreader.cpp
+++ b/Framework/Algorithms/src/CalculateTransmissionBeamSpreader.cpp
@@ -121,7 +121,11 @@ void CalculateTransmissionBeamSpreader::exec() {
   }
 
   // Extract the required spectra into separate workspaces
-  std::vector<detid_t> udets{getProperty("IncidentBeamMonitor")};
+  // The static_cast should not be necessary but it is required to avoid a
+  // "internal compiler error: segmentation fault" when compiling with gcc
+  // and std=c++1z
+  std::vector<detid_t> udets{
+      static_cast<detid_t>(getProperty("IncidentBeamMonitor"))};
 
   // Convert UDETs to workspace indices
   // Get monitors (assume that the detector mapping is the same for all data
diff --git a/Framework/Algorithms/src/CreateSampleWorkspace.cpp b/Framework/Algorithms/src/CreateSampleWorkspace.cpp
index dd1510b819668f6b72cf503f7cf43245892b848b..13689d82fde47e40ca88d32ba64d35a80ba8ea91 100644
--- a/Framework/Algorithms/src/CreateSampleWorkspace.cpp
+++ b/Framework/Algorithms/src/CreateSampleWorkspace.cpp
@@ -383,8 +383,10 @@ EventWorkspace_sptr CreateSampleWorkspace::createEventWorkspace(
   // to find the events per bin
   double sum_of_elems = std::accumulate(yValues.begin(), yValues.end(), 0.0);
   double event_distrib_factor = numEvents / sum_of_elems;
-  std::transform(yValues.begin(), yValues.end(), yValues.begin(),
-                 std::bind1st(std::multiplies<double>(), event_distrib_factor));
+  using std::placeholders::_1;
+  std::transform(
+      yValues.begin(), yValues.end(), yValues.begin(),
+      std::bind(std::multiplies<double>(), event_distrib_factor, _1));
   // the array should now contain the number of events required per bin
 
   // Make fake events
diff --git a/Framework/Algorithms/src/CrossCorrelate.cpp b/Framework/Algorithms/src/CrossCorrelate.cpp
index 80862c9a4abee1367aa73ce613bff551f5f80339..761fded612431eea5e9c465d78ae524a1987b4b0 100644
--- a/Framework/Algorithms/src/CrossCorrelate.cpp
+++ b/Framework/Algorithms/src/CrossCorrelate.cpp
@@ -113,12 +113,13 @@ void CrossCorrelate::exec() {
 
   // Now check if the range between x_min and x_max is valid
   auto &referenceX = inputWS->x(index_ref);
+  using std::placeholders::_1;
   auto minIt = std::find_if(referenceX.cbegin(), referenceX.cend(),
-                            std::bind2nd(std::greater<double>(), xmin));
+                            std::bind(std::greater<double>(), _1, xmin));
   if (minIt == referenceX.cend())
     throw std::runtime_error("No data above XMin");
   auto maxIt = std::find_if(minIt, referenceX.cend(),
-                            std::bind2nd(std::greater<double>(), xmax));
+                            std::bind(std::greater<double>(), _1, xmax));
   if (minIt == maxIt)
     throw std::runtime_error("Range is not valid");
 
diff --git a/Framework/Algorithms/src/FFTSmooth.cpp b/Framework/Algorithms/src/FFTSmooth.cpp
index b4a5f5505b82b9ad8fad9e58677d18b1177989f1..26be4b33f599921ff1d3805619fd88a2ef3e6d8a 100644
--- a/Framework/Algorithms/src/FFTSmooth.cpp
+++ b/Framework/Algorithms/src/FFTSmooth.cpp
@@ -175,10 +175,11 @@ void FFTSmooth::truncate(int n) {
   xr.assign(X.begin(), X.begin() + nx);
   xi.assign(X.begin(), X.begin() + nx);
 
+  using std::placeholders::_1;
   std::transform(yr.begin(), yr.end(), yr.begin(),
-                 std::bind2nd(std::multiplies<double>(), f));
+                 std::bind(std::multiplies<double>(), _1, f));
   std::transform(yi.begin(), yi.end(), yi.begin(),
-                 std::bind2nd(std::multiplies<double>(), f));
+                 std::bind(std::multiplies<double>(), _1, f));
 }
 
 /** Smoothing by zeroing.
diff --git a/Framework/Algorithms/src/GetEi2.cpp b/Framework/Algorithms/src/GetEi2.cpp
index 97be4c087e5f01be1b6333ffd8a9103b4f9072f6..db502a910e68d1c0a4ff5af6dd4dcd16c2df0f04 100644
--- a/Framework/Algorithms/src/GetEi2.cpp
+++ b/Framework/Algorithms/src/GetEi2.cpp
@@ -532,8 +532,9 @@ double GetEi2::calculatePeakWidthAtHalfHeight(
   peak_x.resize(nvalues);
   std::copy(Xs.begin() + im, Xs.begin() + ip + 1, peak_x.begin());
   peak_y.resize(nvalues);
+  using std::placeholders::_1;
   std::transform(Ys.begin() + im, Ys.begin() + ip + 1, peak_y.begin(),
-                 std::bind2nd(std::minus<double>(), bkgd));
+                 std::bind(std::minus<double>(), _1, bkgd));
   peak_e.resize(nvalues);
   std::copy(Es.begin() + im, Es.begin() + ip + 1, peak_e.begin());
 
diff --git a/Framework/Algorithms/src/GetQsInQENSData.cpp b/Framework/Algorithms/src/GetQsInQENSData.cpp
index 9f79cf1522ceb4e2f6e9f6f844b2255dbb3ab987..d880f03a00b495f50aabc75c4ce181e687b066ca 100644
--- a/Framework/Algorithms/src/GetQsInQENSData.cpp
+++ b/Framework/Algorithms/src/GetQsInQENSData.cpp
@@ -113,8 +113,9 @@ MantidVec GetQsInQENSData::extractQValues(
       // Convert Q-values to point values.
       qValues.pop_back();
       qValues.erase(qValues.begin());
+      using std::placeholders::_1;
       std::transform(qValues.begin(), qValues.end(), qValues.begin(),
-                     std::bind2nd(std::divides<double>(), 2.0));
+                     std::bind(std::divides<double>(), _1, 2.0));
     }
   } else {
 
diff --git a/Framework/Algorithms/src/MaxMin.cpp b/Framework/Algorithms/src/MaxMin.cpp
index 7f21d9ac3bddeb01f1ae0a8b85a120bf65d2c942..6b4f1415d41bb9d4ace7ab09203fbb595b1267a3 100644
--- a/Framework/Algorithms/src/MaxMin.cpp
+++ b/Framework/Algorithms/src/MaxMin.cpp
@@ -122,9 +122,11 @@ void MaxMin::exec() {
 
     if (MaxRange == EMPTY_DBL())
       highit = X.end();
-    else
+    else {
+      using std::placeholders::_1;
       highit = std::find_if(lowit, X.end(),
-                            std::bind2nd(std::greater<double>(), MaxRange));
+                            std::bind(std::greater<double>(), _1, MaxRange));
+    }
 
     // If range specified doesn't overlap with this spectrum then bail out
     if (lowit == X.end() || highit == X.begin() || lowit == highit)
diff --git a/Framework/Algorithms/src/Minus.cpp b/Framework/Algorithms/src/Minus.cpp
index 5d8accfc4ffa1d1f7058fa391f9ae6a7d26fc3e6..f5598050c3521146e35cc9966a3e96ac445df13e 100644
--- a/Framework/Algorithms/src/Minus.cpp
+++ b/Framework/Algorithms/src/Minus.cpp
@@ -31,12 +31,13 @@ void Minus::performBinaryOperation(const HistogramData::Histogram &lhs,
                                    const double rhsY, const double rhsE,
                                    HistogramData::HistogramY &YOut,
                                    HistogramData::HistogramE &EOut) {
+  using std::placeholders::_1;
   std::transform(lhs.y().begin(), lhs.y().end(), YOut.begin(),
-                 std::bind2nd(std::minus<double>(), rhsY));
+                 std::bind(std::minus<double>(), _1, rhsY));
   // Only do E if non-zero, otherwise just copy
   if (rhsE != 0)
     std::transform(lhs.e().begin(), lhs.e().end(), EOut.begin(),
-                   std::bind2nd(VectorHelper::SumGaussError<double>(), rhsE));
+                   std::bind(VectorHelper::SumGaussError<double>(), _1, rhsE));
   else
     EOut = lhs.e();
 }
diff --git a/Framework/Algorithms/src/MultiplyRange.cpp b/Framework/Algorithms/src/MultiplyRange.cpp
index a1382503dae4ad410faf872616f5ad6ab1e35d89..7ced286e845dfdd715ad155e6308ae52a5047f55 100644
--- a/Framework/Algorithms/src/MultiplyRange.cpp
+++ b/Framework/Algorithms/src/MultiplyRange.cpp
@@ -90,12 +90,13 @@ void MultiplyRange::exec() {
     auto &newE = outputWS->mutableE(i);
 
     // Now multiply the requested range
+    using std::placeholders::_1;
     std::transform(newY.begin() + startBin, newY.begin() + endBin + 1,
                    newY.begin() + startBin,
-                   std::bind2nd(std::multiplies<double>(), factor));
+                   std::bind(std::multiplies<double>(), _1, factor));
     std::transform(newE.begin() + startBin, newE.begin() + endBin + 1,
                    newE.begin() + startBin,
-                   std::bind2nd(std::multiplies<double>(), factor));
+                   std::bind(std::multiplies<double>(), _1, factor));
 
     progress.report();
     PARALLEL_END_INTERUPT_REGION
diff --git a/Framework/Algorithms/src/Plus.cpp b/Framework/Algorithms/src/Plus.cpp
index b0683314e6d3b2a2d24b54271812c26c9b83ad86..4186592e1d78de1956b8384368aac66e38d365fd 100644
--- a/Framework/Algorithms/src/Plus.cpp
+++ b/Framework/Algorithms/src/Plus.cpp
@@ -34,12 +34,13 @@ void Plus::performBinaryOperation(const HistogramData::Histogram &lhs,
                                   const double rhsY, const double rhsE,
                                   HistogramData::HistogramY &YOut,
                                   HistogramData::HistogramE &EOut) {
+  using std::placeholders::_1;
   std::transform(lhs.y().begin(), lhs.y().end(), YOut.begin(),
-                 std::bind2nd(std::plus<double>(), rhsY));
+                 std::bind(std::plus<double>(), _1, rhsY));
   // Only do E if non-zero, otherwise just copy
   if (rhsE != 0)
     std::transform(lhs.e().begin(), lhs.e().end(), EOut.begin(),
-                   std::bind2nd(VectorHelper::SumGaussError<double>(), rhsE));
+                   std::bind(VectorHelper::SumGaussError<double>(), _1, rhsE));
   else
     EOut = lhs.e();
 }
diff --git a/Framework/Algorithms/src/PointByPointVCorrection.cpp b/Framework/Algorithms/src/PointByPointVCorrection.cpp
index f4fdcc0b63b6eb1ead613efecb0d1796ae31f2db..fce798593e34568049133ffd34280e605e6b8a81 100644
--- a/Framework/Algorithms/src/PointByPointVCorrection.cpp
+++ b/Framework/Algorithms/src/PointByPointVCorrection.cpp
@@ -118,8 +118,9 @@ void PointByPointVCorrection::exec() {
         (error2_factor1 / factor1 / factor1 + error2_factor2);
 
     // Calculate the normalized Y values
+    using std::placeholders::_1;
     // NOTE: Previously, we had been using std::transform with
-    // std::bind2nd(std::multiplies<double>(),factor)
+    // std::bind(std::multiplies<double>(), _1,factor)
     //       here, but that seemed to have strange effects in Windows Debug
     //       builds which caused the unit tests
     //       to sometimes fail.  Maybe this is some compiler bug to do with
diff --git a/Framework/Algorithms/src/Regroup.cpp b/Framework/Algorithms/src/Regroup.cpp
index 4015812d042570695a10351a9e794899979c4c8b..f103098e5d121079d3faf5489732d88fe24ee7d4 100644
--- a/Framework/Algorithms/src/Regroup.cpp
+++ b/Framework/Algorithms/src/Regroup.cpp
@@ -190,8 +190,9 @@ int Regroup::newAxis(const std::vector<double> &params,
   int isteps = ibounds - 1; // highest index in params array containing a step
 
   xcurr = params[0];
+  using std::placeholders::_1;
   auto iup = std::find_if(xold.cbegin(), xold.cend(),
-                          std::bind2nd(std::greater_equal<double>(), xcurr));
+                          std::bind(std::greater_equal<double>(), _1, xcurr));
   if (iup != xold.end()) {
     xcurr = *iup;
     xnew.push_back(xcurr);
@@ -211,7 +212,7 @@ int Regroup::newAxis(const std::vector<double> &params,
 
     // find nearest x_i that is >= xcurr
     iup = std::find_if(xold.begin(), xold.end(),
-                       std::bind2nd(std::greater_equal<double>(), xcurr + xs));
+                       std::bind(std::greater_equal<double>(), _1, xcurr + xs));
     if (iup != xold.end()) {
       if (*iup <= params[ibound]) {
         xcurr = *iup;
diff --git a/Framework/Algorithms/src/ScaleX.cpp b/Framework/Algorithms/src/ScaleX.cpp
index d22944e3226d484054515fc69ed1ca952664a3d7..083720c5286d17e38a7857d8e256434110d15ad1 100644
--- a/Framework/Algorithms/src/ScaleX.cpp
+++ b/Framework/Algorithms/src/ScaleX.cpp
@@ -143,8 +143,9 @@ void ScaleX::exec() {
     if ((i >= m_wi_min) && (i <= m_wi_max)) {
       double factor = getScaleFactor(inputW, i);
       // Do the offsetting
+      using std::placeholders::_1;
       std::transform(inX.begin(), inX.end(), outX.begin(),
-                     std::bind2nd(m_binOp, factor));
+                     std::bind(m_binOp, _1, factor));
       // reverse the vector if multiplicative factor was negative
       if (multiply && factor < 0.0) {
         std::reverse(outX.begin(), outX.end());
diff --git a/Framework/Algorithms/src/SofQWCentre.cpp b/Framework/Algorithms/src/SofQWCentre.cpp
index 735c7787499e284be094e47e6fe79dd497c46633..4f6569accd317cf2aaaceae3bc19ae86c43c54fb 100644
--- a/Framework/Algorithms/src/SofQWCentre.cpp
+++ b/Framework/Algorithms/src/SofQWCentre.cpp
@@ -199,10 +199,11 @@ void SofQWCentre::makeDistribution(API::MatrixWorkspace &outputWS,
   for (size_t i = 0; i < numQBins; ++i) {
     auto &Y = outputWS.mutableY(i);
     auto &E = outputWS.mutableE(i);
+    using std::placeholders::_1;
     std::transform(Y.begin(), Y.end(), Y.begin(),
-                   std::bind2nd(std::divides<double>(), widths[i + 1]));
+                   std::bind(std::divides<double>(), _1, widths[i + 1]));
     std::transform(E.begin(), E.end(), E.begin(),
-                   std::bind2nd(std::divides<double>(), widths[i + 1]));
+                   std::bind(std::divides<double>(), _1, widths[i + 1]));
   }
 }
 
diff --git a/Framework/Algorithms/test/WienerSmoothTest.h b/Framework/Algorithms/test/WienerSmoothTest.h
index e41d28534402841c1183a7b6d07a2760fac183dc..2e23642e37ab259b48dfb7aeaaee2913128084b4 100644
--- a/Framework/Algorithms/test/WienerSmoothTest.h
+++ b/Framework/Algorithms/test/WienerSmoothTest.h
@@ -570,11 +570,11 @@ private:
       std::vector<double> diff(inY.size());
       std::transform(inY.begin(), inY.end(), outY.begin(), diff.begin(),
                      std::minus<double>());
-
+      using std::placeholders::_1;
       auto countPos = std::count_if(diff.begin(), diff.end(),
-                                    std::bind2nd(std::greater<double>(), 0.0));
+                                    std::bind(std::greater<double>(), _1, 0.0));
       auto countNeg = std::count_if(diff.begin(), diff.end(),
-                                    std::bind2nd(std::less<double>(), 0.0));
+                                    std::bind(std::less<double>(), _1, 0.0));
 
       // the delta here is just a guess
       TS_ASSERT_DELTA(double(countPos) / double(countNeg), 1.0, 1e-1);
@@ -646,9 +646,9 @@ private:
       X.assign(x, x + nx);
       Y.assign(y, y + ny);
       E.assign(e, e + ny);
-
+      using std::placeholders::_1;
       std::transform(Y.begin(), Y.end(), Y.begin(),
-                     std::bind2nd(std::multiplies<double>(), double(i + 1)));
+                     std::bind(std::multiplies<double>(), _1, i + 1));
     }
 
     return dataWS;
diff --git a/Framework/Crystal/src/FindSXPeaksHelper.cpp b/Framework/Crystal/src/FindSXPeaksHelper.cpp
index a16628dfd3c1bff42e67c0af8b443613d7472b14..32384c4956811492fe3e8448ab89cb29fbefd57b 100644
--- a/Framework/Crystal/src/FindSXPeaksHelper.cpp
+++ b/Framework/Crystal/src/FindSXPeaksHelper.cpp
@@ -307,12 +307,12 @@ PeakFindingStrategy::getBounds(const HistogramData::HistogramX &x) const {
   auto lowit = (m_minValue == EMPTY_DBL())
                    ? x.begin()
                    : std::lower_bound(x.begin(), x.end(), m_minValue);
-
+  using std::placeholders::_1;
   auto highit =
       (m_maxValue == EMPTY_DBL())
           ? x.end()
           : std::find_if(lowit, x.end(),
-                         std::bind2nd(std::greater<double>(), m_maxValue));
+                         std::bind(std::greater<double>(), _1, m_maxValue));
 
   return std::make_pair(lowit, highit);
 }
diff --git a/Framework/CurveFitting/src/Algorithms/QENSFitSequential.cpp b/Framework/CurveFitting/src/Algorithms/QENSFitSequential.cpp
index a8d8dc6148da074671a7c96ec24af801533bfd28..61e0c7df518931e1090a97afb35af30b3886032a 100644
--- a/Framework/CurveFitting/src/Algorithms/QENSFitSequential.cpp
+++ b/Framework/CurveFitting/src/Algorithms/QENSFitSequential.cpp
@@ -753,7 +753,11 @@ std::vector<MatrixWorkspace_sptr> QENSFitSequential::getWorkspaces() const {
   const auto inputString = getPropertyValue("Input");
   if (!inputString.empty())
     return extractWorkspaces(inputString);
-  return {getProperty("InputWorkspace")};
+  // The static_cast should not be necessary but it is required to avoid a
+  // "internal compiler error: segmentation fault" when compiling with gcc
+  // and std=c++1z
+  return std::vector<MatrixWorkspace_sptr>{
+      static_cast<MatrixWorkspace_sptr>(getProperty("InputWorkspace"))};
 }
 
 std::vector<MatrixWorkspace_sptr> QENSFitSequential::convertInputToElasticQ(
diff --git a/Framework/CurveFitting/src/Algorithms/VesuvioCalculateGammaBackground.cpp b/Framework/CurveFitting/src/Algorithms/VesuvioCalculateGammaBackground.cpp
index 6dbd0635a061169da72a68c1611190bff9fd573a..20f0bc4a238446cd0cedb6017579199242d99d4a 100644
--- a/Framework/CurveFitting/src/Algorithms/VesuvioCalculateGammaBackground.cpp
+++ b/Framework/CurveFitting/src/Algorithms/VesuvioCalculateGammaBackground.cpp
@@ -32,6 +32,7 @@ using namespace Kernel;
 using namespace CurveFitting;
 using namespace CurveFitting::Functions;
 using namespace std;
+using std::placeholders::_1;
 
 // Subscription
 DECLARE_ALGORITHM(VesuvioCalculateGammaBackground)
@@ -255,7 +256,7 @@ void VesuvioCalculateGammaBackground::calculateSpectrumFromDetector(
   // Correct for distance to the detector: 0.5/l2^2
   const double detDistCorr = 0.5 / detPar.l2 / detPar.l2;
   std::transform(ctdet.begin(), ctdet.end(), ctdet.begin(),
-                 std::bind2nd(std::multiplies<double>(), detDistCorr));
+                 std::bind(std::multiplies<double>(), _1, detDistCorr));
 }
 
 /**
@@ -302,7 +303,7 @@ void VesuvioCalculateGammaBackground::calculateBackgroundFromFoils(
   if (reversed) {
     // The reversed ones should be (C0 - C1)
     std::transform(ctfoil.begin(), ctfoil.end(), ctfoil.begin(),
-                   std::bind2nd(std::multiplies<double>(), -1.0));
+                   std::bind(std::multiplies<double>(), _1, -1.0));
   }
 }
 
@@ -398,7 +399,7 @@ std::vector<double> VesuvioCalculateGammaBackground::calculateTofSpectrum(
   // Assumes the input is in seconds, transform it temporarily
   auto &tseconds = m_backgroundWS->mutableX(wsIndex);
   std::transform(tseconds.begin(), tseconds.end(), tseconds.begin(),
-                 std::bind2nd(std::multiplies<double>(), 1e-6));
+                 std::bind(std::multiplies<double>(), _1, 1e-6));
 
   // retrieveInputs ensures we will get a composite function and that each
   // member is a ComptonProfile
@@ -429,7 +430,7 @@ std::vector<double> VesuvioCalculateGammaBackground::calculateTofSpectrum(
   }
   // Put X back microseconds
   std::transform(tseconds.begin(), tseconds.end(), tseconds.begin(),
-                 std::bind2nd(std::multiplies<double>(), 1e6));
+                 std::bind(std::multiplies<double>(), _1, 1e6));
   return correctedVals;
 }
 
diff --git a/Framework/CurveFitting/src/Functions/ChebfunBase.cpp b/Framework/CurveFitting/src/Functions/ChebfunBase.cpp
index 460e7d719ee5afe8a63ab81b225c1c894abf2984..808c69daf4fd37753ac218814da73cc681183821 100644
--- a/Framework/CurveFitting/src/Functions/ChebfunBase.cpp
+++ b/Framework/CurveFitting/src/Functions/ChebfunBase.cpp
@@ -316,9 +316,10 @@ void ChebfunBase::derivative(const std::vector<double> &a,
   } else {
     aout.front() = a[1];
   }
-  double d = (m_end - m_start) / 2;
-  std::transform(aout.begin(), aout.end(), aout.begin(),
-                 std::bind2nd(std::divides<double>(), d));
+  using std::placeholders::_1;
+  std::transform(
+      aout.begin(), aout.end(), aout.begin(),
+      std::bind(std::divides<double>(), _1, 0.5 * (m_end - m_start)));
 }
 
 /**
diff --git a/Framework/CurveFitting/src/Functions/ComptonPeakProfile.cpp b/Framework/CurveFitting/src/Functions/ComptonPeakProfile.cpp
index 4c2e6e27ef7896e8ace4269049cfb8bc6e36a0ae..c1b3c66c1631e18f6a4f5849a1e42f0e89370887 100644
--- a/Framework/CurveFitting/src/Functions/ComptonPeakProfile.cpp
+++ b/Framework/CurveFitting/src/Functions/ComptonPeakProfile.cpp
@@ -68,8 +68,9 @@ void ComptonPeakProfile::function1D(double *out, const double *xValues,
     m_voigt->setParameter(3, gaussFWHM);
     m_voigt->functionLocal(out, xValues, nData);
     const double norm = 1.0 / (0.5 * M_PI * lorentzFWHM);
+    using std::placeholders::_1;
     std::transform(out, out + nData, out,
-                   std::bind2nd(std::multiplies<double>(), norm));
+                   std::bind(std::multiplies<double>(), _1, norm));
   } else {
     double sigmaTotalSq =
         m_hwhmLorentz * m_hwhmLorentz + gaussSigma * gaussSigma;
diff --git a/Framework/CurveFitting/src/Functions/ComptonProfile.cpp b/Framework/CurveFitting/src/Functions/ComptonProfile.cpp
index 2337c466604e5b9355910aa7b518502f722f44b8..5f64c9685f9f896a2946e5f05cea16b9ab59b8c8 100644
--- a/Framework/CurveFitting/src/Functions/ComptonProfile.cpp
+++ b/Framework/CurveFitting/src/Functions/ComptonProfile.cpp
@@ -203,15 +203,16 @@ void ComptonProfile::voigtApproxDiff(std::vector<double> &voigtDiff,
 
   std::vector<double> ypmEps(yspace.size());
   // y+2eps
+  using std::placeholders::_1;
   std::transform(
       yspace.begin(), yspace.end(), ypmEps.begin(),
-      std::bind2nd(std::plus<double>(), 2.0 * epsilon)); // Add 2 epsilon
+      std::bind(std::plus<double>(), _1, 2.0 * epsilon)); // Add 2 epsilon
   m_resolutionFunction->voigtApprox(voigtDiff, ypmEps, lorentzPos, lorentzAmp,
                                     lorentzWidth, gaussWidth);
   // y-2eps
   std::transform(
       yspace.begin(), yspace.end(), ypmEps.begin(),
-      std::bind2nd(std::minus<double>(), 2.0 * epsilon)); // Subtract 2 epsilon
+      std::bind(std::minus<double>(), _1, 2.0 * epsilon)); // Subtract 2 epsilon
   std::vector<double> tmpResult(yspace.size());
   m_resolutionFunction->voigtApprox(tmpResult, ypmEps, lorentzPos, lorentzAmp,
                                     lorentzWidth, gaussWidth);
@@ -221,11 +222,11 @@ void ComptonProfile::voigtApproxDiff(std::vector<double> &voigtDiff,
 
   // y+eps
   std::transform(yspace.begin(), yspace.end(), ypmEps.begin(),
-                 std::bind2nd(std::plus<double>(), epsilon)); // Add epsilon
+                 std::bind(std::plus<double>(), _1, epsilon)); // Add epsilon
   m_resolutionFunction->voigtApprox(tmpResult, ypmEps, lorentzPos, lorentzAmp,
                                     lorentzWidth, gaussWidth);
   std::transform(tmpResult.begin(), tmpResult.end(), tmpResult.begin(),
-                 std::bind2nd(std::multiplies<double>(), 2.0)); // times 2
+                 std::bind(std::multiplies<double>(), _1, 2.0)); // times 2
   // Difference with 3rd term - result is put back in voigtDiff
   std::transform(voigtDiff.begin(), voigtDiff.end(), tmpResult.begin(),
                  voigtDiff.begin(), std::minus<double>());
@@ -233,20 +234,19 @@ void ComptonProfile::voigtApproxDiff(std::vector<double> &voigtDiff,
   // y-eps
   std::transform(
       yspace.begin(), yspace.end(), ypmEps.begin(),
-      std::bind2nd(std::minus<double>(), epsilon)); // Subtract epsilon
+      std::bind(std::minus<double>(), _1, epsilon)); // Subtract epsilon
   m_resolutionFunction->voigtApprox(tmpResult, ypmEps, lorentzPos, lorentzAmp,
                                     lorentzWidth, gaussWidth);
   std::transform(tmpResult.begin(), tmpResult.end(), tmpResult.begin(),
-                 std::bind2nd(std::multiplies<double>(), 2.0)); // times 2
+                 std::bind(std::multiplies<double>(), _1, 2.0)); // times 2
   // Sum final term
   std::transform(voigtDiff.begin(), voigtDiff.end(), tmpResult.begin(),
                  voigtDiff.begin(), std::plus<double>());
 
-  // Finally multiply by 2*eps^3
+  // Finally divide by 2*eps^3
   std::transform(
       voigtDiff.begin(), voigtDiff.end(), voigtDiff.begin(),
-      std::bind2nd(std::divides<double>(),
-                   2.0 * std::pow(epsilon, 3))); // divided by (2eps^3)
+      std::bind(std::divides<double>(), _1, 2.0 * std::pow(epsilon, 3)));
 }
 
 } // namespace Functions
diff --git a/Framework/CurveFitting/src/Functions/Convolution.cpp b/Framework/CurveFitting/src/Functions/Convolution.cpp
index 3b440e7062e03cc9e8a1fda383d0f8f929d2ae02..0831c2e8897d5209d716e2d07ba2564756905b86 100644
--- a/Framework/CurveFitting/src/Functions/Convolution.cpp
+++ b/Framework/CurveFitting/src/Functions/Convolution.cpp
@@ -34,10 +34,9 @@ namespace CurveFitting {
 namespace Functions {
 
 using namespace CurveFitting;
-
 using namespace Kernel;
-
 using namespace API;
+using std::placeholders::_1;
 
 DECLARE_FUNCTION(Convolution)
 
@@ -183,7 +182,7 @@ void Convolution::functionFFTMode(const FunctionDomain &domain,
                            workspace.workspace);
     std::transform(m_resolution.begin(), m_resolution.end(),
                    m_resolution.begin(),
-                   std::bind2nd(std::multiplies<double>(), dx));
+                   std::bind(std::multiplies<double>(), _1, dx));
   }
 
   // Now m_resolution contains fourier transform of the resolution
@@ -193,7 +192,7 @@ void Convolution::functionFFTMode(const FunctionDomain &domain,
     double dx = 1.; // nData > 1? xValues[1] - xValues[0]: 1.;
     std::transform(m_resolution.begin(), m_resolution.end(),
                    values.getPointerToCalculated(0),
-                   std::bind2nd(std::multiplies<double>(), dx));
+                   std::bind(std::multiplies<double>(), _1, dx));
     return;
   }
 
@@ -247,7 +246,7 @@ void Convolution::functionFFTMode(const FunctionDomain &domain,
     // integration variable
     double dx = nData > 1 ? xValues[1] - xValues[0] : 1.;
     std::transform(out, out + nData, out,
-                   std::bind2nd(std::multiplies<double>(), dx));
+                   std::bind(std::multiplies<double>(), _1, dx));
 
     // now out contains fourier transform of the model function
 
@@ -276,7 +275,7 @@ void Convolution::functionFFTMode(const FunctionDomain &domain,
     // integration variable
     dx = nData > 1 ? 1. / (xValues[1] - xValues[0]) : 1.;
     std::transform(out, out + nData, out,
-                   std::bind2nd(std::multiplies<double>(), dx));
+                   std::bind(std::multiplies<double>(), _1, dx));
   } else {
     values.zeroCalculated();
   }
@@ -287,7 +286,7 @@ void Convolution::functionFFTMode(const FunctionDomain &domain,
     std::vector<double> tmp(nData);
     resolution->function1D(tmp.data(), xValues, nData);
     std::transform(tmp.begin(), tmp.end(), tmp.begin(),
-                   std::bind2nd(std::multiplies<double>(), dltF));
+                   std::bind(std::multiplies<double>(), _1, dltF));
     std::transform(out, out + nData, tmp.data(), out, std::plus<double>());
   } else if (!dltFuns.empty()) {
     std::vector<double> x(nData);
@@ -295,11 +294,11 @@ void Convolution::functionFFTMode(const FunctionDomain &domain,
       double shift = -df->getParameter("Centre");
       dltF = df->getParameter("Height") * df->HeightPrefactor();
       std::transform(xValues, xValues + nData, x.data(),
-                     std::bind2nd(std::plus<double>(), shift));
+                     std::bind(std::plus<double>(), _1, shift));
       std::vector<double> tmp(nData);
       resolution->function1D(tmp.data(), x.data(), nData);
       std::transform(tmp.begin(), tmp.end(), tmp.begin(),
-                     std::bind2nd(std::multiplies<double>(), dltF));
+                     std::bind(std::multiplies<double>(), _1, dltF));
       std::transform(out, out + nData, tmp.data(), out, std::plus<double>());
     }
   }
@@ -417,7 +416,7 @@ void Convolution::functionDirectMode(const FunctionDomain &domain,
     std::vector<double> tmp(nData);
     resolution->function1D(tmp.data(), xValues, nData);
     std::transform(tmp.begin(), tmp.end(), tmp.begin(),
-                   std::bind2nd(std::multiplies<double>(), dltF));
+                   std::bind(std::multiplies<double>(), _1, dltF));
     std::transform(out, out + nData, tmp.data(), out, std::plus<double>());
   } else if (!dltFuns.empty()) {
     std::vector<double> x(nData);
@@ -425,11 +424,11 @@ void Convolution::functionDirectMode(const FunctionDomain &domain,
       double shift = -df->getParameter("Centre");
       dltF = df->getParameter("Height") * df->HeightPrefactor();
       std::transform(xValues, xValues + nData, x.data(),
-                     std::bind2nd(std::plus<double>(), shift));
+                     std::bind(std::plus<double>(), _1, shift));
       std::vector<double> tmp(nData);
       resolution->function1D(tmp.data(), x.data(), nData);
       std::transform(tmp.begin(), tmp.end(), tmp.begin(),
-                     std::bind2nd(std::multiplies<double>(), dltF));
+                     std::bind(std::multiplies<double>(), _1, dltF));
       std::transform(out, out + nData, tmp.data(), out, std::plus<double>());
     }
   }
diff --git a/Framework/CurveFitting/src/Functions/GramCharlierComptonProfile.cpp b/Framework/CurveFitting/src/Functions/GramCharlierComptonProfile.cpp
index af3294cd0db0b7a3ebbcf4ebfe830ebc36bde906..6d5cd021a0e0ae63b1a35055ae09183df7fc61ba 100644
--- a/Framework/CurveFitting/src/Functions/GramCharlierComptonProfile.cpp
+++ b/Framework/CurveFitting/src/Functions/GramCharlierComptonProfile.cpp
@@ -428,8 +428,9 @@ void GramCharlierComptonProfile::cacheYSpaceValues(
 
   // Cache voigt function over yfine
   std::vector<double> minusYFine(NFINE_Y);
+  using std::placeholders::_1;
   std::transform(m_yfine.begin(), m_yfine.end(), minusYFine.begin(),
-                 std::bind2nd(std::multiplies<double>(), -1.0));
+                 std::bind(std::multiplies<double>(), _1, -1.0));
   std::vector<double> ym(
       NFINE_Y); // Holds result of (y[i] - yfine) for each original y
   m_voigt.resize(ncoarseY);
@@ -441,7 +442,7 @@ void GramCharlierComptonProfile::cacheYSpaceValues(
     const double yi = yspace[i];
     std::transform(
         minusYFine.begin(), minusYFine.end(), ym.begin(),
-        std::bind2nd(std::plus<double>(), yi)); // yfine is actually -yfine
+        std::bind(std::plus<double>(), _1, yi)); // yfine is actually -yfine
     m_resolutionFunction->voigtApprox(voigt, ym, 0, 1.0);
   }
 
diff --git a/Framework/CurveFitting/src/Functions/VesuvioResolution.cpp b/Framework/CurveFitting/src/Functions/VesuvioResolution.cpp
index bdc065ef2098f8753ce40f03be2fe12d258d8e2d..e58687711f6cf3a2ed4173f66abd9d8ca39e26fc 100644
--- a/Framework/CurveFitting/src/Functions/VesuvioResolution.cpp
+++ b/Framework/CurveFitting/src/Functions/VesuvioResolution.cpp
@@ -247,8 +247,9 @@ void VesuvioResolution::voigtApprox(std::vector<double> &voigt,
 
   // Normalize so that integral of V=lorentzAmp
   const double norm = 1.0 / (0.5 * M_PI * lorentzWidth);
+  using std::placeholders::_1;
   std::transform(voigt.begin(), voigt.end(), voigt.begin(),
-                 std::bind2nd(std::multiplies<double>(), norm));
+                 std::bind(std::multiplies<double>(), _1, norm));
 }
 
 } // namespace Functions
diff --git a/Framework/CurveFitting/test/Algorithms/CalculateChiSquaredTest.h b/Framework/CurveFitting/test/Algorithms/CalculateChiSquaredTest.h
index 3277c264db06172d4201ab05967f99c567aded32..5c95a66db243b198d8368f00f4fcd4616b1623ae 100644
--- a/Framework/CurveFitting/test/Algorithms/CalculateChiSquaredTest.h
+++ b/Framework/CurveFitting/test/Algorithms/CalculateChiSquaredTest.h
@@ -293,8 +293,9 @@ private:
       }
       if (isHisto) {
         xValues.resize(nData);
+        using std::placeholders::_1;
         std::transform(xBins.begin(), xBins.end() - 1, xValues.begin(),
-                       std::bind2nd(std::plus<double>(), dx / 2));
+                       std::bind(std::plus<double>(), _1, dx / 2));
       } else {
         xValues = xBins;
       }
diff --git a/Framework/CurveFitting/test/Algorithms/EvaluateFunctionTest.h b/Framework/CurveFitting/test/Algorithms/EvaluateFunctionTest.h
index e04c5cc2bea230d53496ec1c9bf13b7cef2dd217..4cacab7e7a1ea47c48ab87a91f91d5efca53ffb8 100644
--- a/Framework/CurveFitting/test/Algorithms/EvaluateFunctionTest.h
+++ b/Framework/CurveFitting/test/Algorithms/EvaluateFunctionTest.h
@@ -191,17 +191,17 @@ private:
       for (size_t i = 0; i < xBins.size(); ++i) {
         xBins[i] = xMin + double(i) * dx;
       }
-
+      using std::placeholders::_1;
       if (workspaceIndex > 0) {
         std::transform(
             xBins.begin(), xBins.end(), xBins.begin(),
-            std::bind2nd(std::plus<double>(), double(workspaceIndex)));
+            std::bind(std::plus<double>(), _1, double(workspaceIndex)));
       }
 
       if (isHisto) {
         xValues.resize(nData);
         std::transform(xBins.begin(), xBins.end() - 1, xValues.begin(),
-                       std::bind2nd(std::plus<double>(), dx / 2));
+                       std::bind(std::plus<double>(), _1, dx / 2));
       } else {
         xValues = xBins;
       }
diff --git a/Framework/CurveFitting/test/Functions/ComptonScatteringCountRateTest.h b/Framework/CurveFitting/test/Functions/ComptonScatteringCountRateTest.h
index 7b1dc1176cbf0326a3e915a4db7001c5013cd3d2..4c43050a0850bbba9bc56e693a488b8e16e90d14 100644
--- a/Framework/CurveFitting/test/Functions/ComptonScatteringCountRateTest.h
+++ b/Framework/CurveFitting/test/Functions/ComptonScatteringCountRateTest.h
@@ -83,9 +83,10 @@ public:
     auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
         1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
     auto &dataX = testWS->mutableX(0);
+    using std::placeholders::_1;
     std::transform(
         dataX.begin(), dataX.end(), dataX.begin(),
-        std::bind2nd(std::multiplies<double>(), 1e-06)); // to seconds
+        std::bind(std::multiplies<double>(), _1, 1e-06)); // to seconds
     func->setMatrixWorkspace(testWS, 0, dataX.front(), dataX.back());
     FunctionDomain1DView domain(&dataX.front(), dataX.size());
     FunctionValues values(domain);
diff --git a/Framework/CurveFitting/test/Functions/GaussianComptonProfileTest.h b/Framework/CurveFitting/test/Functions/GaussianComptonProfileTest.h
index 2245f9b49ce6db42db4ecee8643101d8af59e3cb..6b7c94ed28f73af6b944c1b3d89f9f97539e2995 100644
--- a/Framework/CurveFitting/test/Functions/GaussianComptonProfileTest.h
+++ b/Framework/CurveFitting/test/Functions/GaussianComptonProfileTest.h
@@ -62,9 +62,10 @@ public:
     auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
         1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
     auto &dataX = testWS->dataX(0);
+    using std::placeholders::_1;
     std::transform(
         dataX.begin(), dataX.end(), dataX.begin(),
-        std::bind2nd(std::multiplies<double>(), 1e-06)); // to seconds
+        std::bind(std::multiplies<double>(), _1, 1e-06)); // to seconds
     func->setMatrixWorkspace(testWS, 0, dataX.front(), dataX.back());
     FunctionDomain1DView domain(dataX.data(), dataX.size());
     FunctionValues values(domain);
diff --git a/Framework/CurveFitting/test/Functions/GramCharlierComptonProfileTest.h b/Framework/CurveFitting/test/Functions/GramCharlierComptonProfileTest.h
index 15859cad4d288fd793002fd19604d4a12418422f..96b7f454400c201ab9e806543aba0b6dcd1c3390 100644
--- a/Framework/CurveFitting/test/Functions/GramCharlierComptonProfileTest.h
+++ b/Framework/CurveFitting/test/Functions/GramCharlierComptonProfileTest.h
@@ -92,9 +92,10 @@ public:
     auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
         1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
     auto &dataX = testWS->dataX(0);
+    using std::placeholders::_1;
     std::transform(
         dataX.begin(), dataX.end(), dataX.begin(),
-        std::bind2nd(std::multiplies<double>(), 1e-06)); // to seconds
+        std::bind(std::multiplies<double>(), _1, 1e-06)); // to seconds
     func->setMatrixWorkspace(testWS, 0, dataX.front(), dataX.back());
     FunctionDomain1DView domain(dataX.data(), dataX.size());
     FunctionValues values(domain);
diff --git a/Framework/CurveFitting/test/Functions/InelasticIsoRotDiffTest.h b/Framework/CurveFitting/test/Functions/InelasticIsoRotDiffTest.h
index 1252106eb14126bfed29200eec5d5a58dc22e005..17c5f0c68b9b7ef01ba48350b563f65bec960f85 100644
--- a/Framework/CurveFitting/test/Functions/InelasticIsoRotDiffTest.h
+++ b/Framework/CurveFitting/test/Functions/InelasticIsoRotDiffTest.h
@@ -88,15 +88,16 @@ public:
     // Create the domain of energy values
     std::vector<double> xValues(nData, 0);
     std::iota(xValues.begin(), xValues.end(), -10000.0);
+    using std::placeholders::_1;
     std::transform(xValues.begin(), xValues.end(), xValues.begin(),
-                   std::bind1st(std::multiplies<double>(), dE));
+                   std::bind(std::multiplies<double>(), dE, _1));
     // Evaluate the function on the domain
     std::vector<double> calculatedValues(nData, 0);
     func->function1D(calculatedValues.data(), xValues.data(), nData);
     // Integrate the evaluation
     std::transform(calculatedValues.begin(), calculatedValues.end(),
                    calculatedValues.begin(),
-                   std::bind1st(std::multiplies<double>(), dE));
+                   std::bind(std::multiplies<double>(), dE, _1));
     auto integral =
         std::accumulate(calculatedValues.begin(), calculatedValues.end(), 0.0);
     std::cout << integral << std::endl;
diff --git a/Framework/CurveFitting/test/Functions/MultivariateGaussianComptonProfileTest.h b/Framework/CurveFitting/test/Functions/MultivariateGaussianComptonProfileTest.h
index 3277b0a1161455db42145e5e9d5fd345cbaf9290..8014ed212149507ceff1a3a2722e1e0ad302cbaa 100644
--- a/Framework/CurveFitting/test/Functions/MultivariateGaussianComptonProfileTest.h
+++ b/Framework/CurveFitting/test/Functions/MultivariateGaussianComptonProfileTest.h
@@ -77,9 +77,10 @@ public:
     auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
         1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
     auto &dataX = testWS->dataX(0);
+    using std::placeholders::_1;
     std::transform(
         dataX.begin(), dataX.end(), dataX.begin(),
-        std::bind2nd(std::multiplies<double>(), 1e-06)); // to seconds
+        std::bind(std::multiplies<double>(), _1, 1e-06)); // to seconds
     func->setMatrixWorkspace(testWS, 0, dataX.front(), dataX.back());
     FunctionDomain1DView domain(dataX.data(), dataX.size());
     FunctionValues values(domain);
diff --git a/Framework/CurveFitting/test/Functions/TeixeiraWaterSQETest.h b/Framework/CurveFitting/test/Functions/TeixeiraWaterSQETest.h
index 63640d1300192aee8f4bf719320178063a92598b..8ebdca8bc53ccd2d8ee60bb4a7862d4019960af2 100644
--- a/Framework/CurveFitting/test/Functions/TeixeiraWaterSQETest.h
+++ b/Framework/CurveFitting/test/Functions/TeixeiraWaterSQETest.h
@@ -67,15 +67,16 @@ public:
     // Create the domain of energy values
     std::vector<double> xValues(nData, 0);
     std::iota(xValues.begin(), xValues.end(), -10000.0);
+    using std::placeholders::_1;
     std::transform(xValues.begin(), xValues.end(), xValues.begin(),
-                   std::bind1st(std::multiplies<double>(), dE));
+                   std::bind(std::multiplies<double>(), dE, _1));
     // Evaluate the function on the domain
     std::vector<double> calculatedValues(nData, 0);
     func->function1D(calculatedValues.data(), xValues.data(), nData);
     // Integrate the evaluation
     std::transform(calculatedValues.begin(), calculatedValues.end(),
                    calculatedValues.begin(),
-                   std::bind1st(std::multiplies<double>(), dE));
+                   std::bind(std::multiplies<double>(), dE, _1));
     auto integral =
         std::accumulate(calculatedValues.begin(), calculatedValues.end(), 0.0);
     TS_ASSERT_DELTA(integral, 1.0, 0.01);
diff --git a/Framework/CurveFitting/test/Functions/VesuvioResolutionTest.h b/Framework/CurveFitting/test/Functions/VesuvioResolutionTest.h
index be95236e63d272149c457f305051b6cb2efafd5b..0149e9f42c9f154a83524e7de3644e7737fadaf1 100644
--- a/Framework/CurveFitting/test/Functions/VesuvioResolutionTest.h
+++ b/Framework/CurveFitting/test/Functions/VesuvioResolutionTest.h
@@ -43,9 +43,10 @@ public:
     auto testWS = ComptonProfileTestHelpers::createTestWorkspace(
         1, x0, x1, dx, ComptonProfileTestHelpers::NoiseType::None);
     auto &dataX = testWS->dataX(0);
+    using std::placeholders::_1;
     std::transform(
         dataX.begin(), dataX.end(), dataX.begin(),
-        std::bind2nd(std::multiplies<double>(), 1e-06)); // to seconds
+        std::bind(std::multiplies<double>(), _1, 1e-06)); // to seconds
     func->setMatrixWorkspace(testWS, 0, dataX.front(), dataX.back());
     FunctionDomain1DView domain(dataX.data(), dataX.size());
     FunctionValues values(domain);
diff --git a/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp b/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp
index 5b49cd974cdc3feae4a9dfa79b478dc56a21f51e..b6fadad0a208a8f63b1a21b9aaf85940144ee650 100644
--- a/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp
+++ b/Framework/DataHandling/src/FilterEventsByLogValuePreNexus.cpp
@@ -2277,8 +2277,9 @@ void FilterEventsByLogValuePreNexus::loadPixelMap(const std::string &filename) {
   this->m_pixelmap = pixelmapFile.loadAllIntoVector();
 
   // Check for funky file
+  using std::placeholders::_1;
   if (std::find_if(m_pixelmap.begin(), m_pixelmap.end(),
-                   std::bind2nd(std::greater<PixelType>(), max_pid)) !=
+                   std::bind(std::greater<PixelType>(), _1, max_pid)) !=
       m_pixelmap.end()) {
     this->g_log.warning("Pixel id in mapping file was out of bounds. Loading "
                         "without mapping file");
diff --git a/Framework/DataHandling/src/LoadEventNexus.cpp b/Framework/DataHandling/src/LoadEventNexus.cpp
index fcd159d8e11e2f570ffe5c2a5772c62c7e353c81..2c770928dd7e02887d5d5e3a4984bac894e9cd7c 100644
--- a/Framework/DataHandling/src/LoadEventNexus.cpp
+++ b/Framework/DataHandling/src/LoadEventNexus.cpp
@@ -29,7 +29,6 @@
 #include "MantidKernel/VisibleWhenProperty.h"
 
 #include <H5Cpp.h>
-#include <boost/function.hpp>
 #include <boost/shared_array.hpp>
 #include <boost/shared_ptr.hpp>
 
@@ -355,9 +354,9 @@ template <>
 void LoadEventNexus::filterDuringPause<EventWorkspaceCollection_sptr>(
     EventWorkspaceCollection_sptr workspace) {
   // We provide a function pointer to the filter method of the object
-  boost::function<void(MatrixWorkspace_sptr)> func = std::bind1st(
-      std::mem_fun(&LoadEventNexus::filterDuringPause<MatrixWorkspace_sptr>),
-      this);
+  using std::placeholders::_1;
+  auto func = std::bind(
+      &LoadEventNexus::filterDuringPause<MatrixWorkspace_sptr>, this, _1);
   workspace->applyFilter(func);
 }
 
diff --git a/Framework/DataHandling/src/LoadEventPreNexus2.cpp b/Framework/DataHandling/src/LoadEventPreNexus2.cpp
index afb463bcd0ba29b489dbd2fde294effb25f11a05..37c0f6dab65095726432708be5e1ce760289d800 100644
--- a/Framework/DataHandling/src/LoadEventPreNexus2.cpp
+++ b/Framework/DataHandling/src/LoadEventPreNexus2.cpp
@@ -1236,8 +1236,9 @@ void LoadEventPreNexus2::loadPixelMap(const std::string &filename) {
   this->pixelmap = pixelmapFile.loadAllIntoVector();
 
   // Check for funky file
+  using std::placeholders::_1;
   if (std::find_if(pixelmap.begin(), pixelmap.end(),
-                   std::bind2nd(std::greater<PixelType>(), max_pid)) !=
+                   std::bind(std::greater<PixelType>(), _1, max_pid)) !=
       pixelmap.end()) {
     this->g_log.warning("Pixel id in mapping file was out of bounds. Loading "
                         "without mapping file");
diff --git a/Framework/DataHandling/src/LoadNexusLogs.cpp b/Framework/DataHandling/src/LoadNexusLogs.cpp
index e82bea4e09f6910e757d132f9d3c66bc801161ed..9162a9df98a5da6137babb001cacaaf3d2e81590 100644
--- a/Framework/DataHandling/src/LoadNexusLogs.cpp
+++ b/Framework/DataHandling/src/LoadNexusLogs.cpp
@@ -689,8 +689,9 @@ LoadNexusLogs::createTimeSeries(::NeXus::File &file,
 
   // Convert to seconds if needed
   if (time_units == "minutes") {
+    using std::placeholders::_1;
     std::transform(time_double.begin(), time_double.end(), time_double.begin(),
-                   std::bind2nd(std::multiplies<double>(), 60.0));
+                   std::bind(std::multiplies<double>(), _1, 60.0));
   }
   // Now the values: Could be a string, int or double
   file.openData("value");
diff --git a/Framework/DataHandling/src/LoadRawHelper.cpp b/Framework/DataHandling/src/LoadRawHelper.cpp
index 56fe99c6a685a7de6807ddd682a969787d331c0c..47f300714ae38e28165cb2ac2393e9a0abed3431 100644
--- a/Framework/DataHandling/src/LoadRawHelper.cpp
+++ b/Framework/DataHandling/src/LoadRawHelper.cpp
@@ -510,9 +510,10 @@ LoadRawHelper::getTimeChannels(const int64_t &regimes,
       g_log.debug() << "Time regime " << i + 1 << " shifted by " << shift
                     << " microseconds\n";
       // Add on the shift for this vector
+      using std::placeholders::_1;
       std::transform(channelsVec->begin(), channelsVec->end(),
                      channelsVec->begin(),
-                     std::bind2nd(std::plus<double>(), shift));
+                     std::bind(std::plus<double>(), _1, shift));
       timeChannelsVec.push_back(channelsVec);
     }
     // In this case, also need to populate the map of spectrum-regime
diff --git a/Framework/DataHandling/src/SaveCanSAS1D.cpp b/Framework/DataHandling/src/SaveCanSAS1D.cpp
index b79e350b2e27f395d538f71c534a5f42080ce748..380a0ed53132a46a0b872ac0d4ba0f670441f735 100644
--- a/Framework/DataHandling/src/SaveCanSAS1D.cpp
+++ b/Framework/DataHandling/src/SaveCanSAS1D.cpp
@@ -560,8 +560,9 @@ void SaveCanSAS1D::createSASDetectorElement(std::string &sasDet) {
   }
 
   std::list<std::string> detList;
+  using std::placeholders::_1;
   boost::algorithm::split(detList, detectorNames,
-                          std::bind2nd(std::equal_to<char>(), ','));
+                          std::bind(std::equal_to<char>(), _1, ','));
   for (auto detectorName : detList) {
     boost::algorithm::trim(detectorName);
 
diff --git a/Framework/DataHandling/src/SaveISISNexus.cpp b/Framework/DataHandling/src/SaveISISNexus.cpp
index 277f7782ab3e612e8bd7a6d18ed3ab8e0ac942b5..cec7fefa984e155f9d157cad88c602dbc702cfbc 100644
--- a/Framework/DataHandling/src/SaveISISNexus.cpp
+++ b/Framework/DataHandling/src/SaveISISNexus.cpp
@@ -817,8 +817,9 @@ void SaveISISNexus::runlog() {
   fil.close();
 
   run_status_vec.resize(time_vec.size());
+  using std::placeholders::_1;
   std::transform(is_running_vec.begin(), is_running_vec.end(),
-                 run_status_vec.begin(), std::bind2nd(std::plus<int>(), 1));
+                 run_status_vec.begin(), std::bind(std::plus<int>(), _1, 1));
 
   NXmakegroup(handle, "runlog", "IXrunlog");
   NXopengroup(handle, "runlog", "IXrunlog");
diff --git a/Framework/Geometry/src/Math/Acomp.cpp b/Framework/Geometry/src/Math/Acomp.cpp
index 932e9810471351cd978f4ed93eeb689e4fc62438..b9f4fcbf9ad124cbeb8727d80334b702ce122ab8 100644
--- a/Framework/Geometry/src/Math/Acomp.cpp
+++ b/Framework/Geometry/src/Math/Acomp.cpp
@@ -758,7 +758,7 @@ literals
   }
   // Doesn't work because literal map is a reference
   //  for_each(Comp.begin(),Comp.end(),
-  // std::bind2nd(std::mem_fun(&Acomp::getLiterals),literalMap));
+  // std::bind2nd(std::mem_fun(&Acomp::getLiterals), literalMap));
 }
 
 int Acomp::isSimple() const
@@ -836,8 +836,9 @@ i.e. one pass.
     Work.erase(uend, Work.end());
     Tmod.clear(); // erase all at the start
     // set PI status to 1
+    using std::placeholders::_1;
     for_each(Work.begin(), Work.end(),
-             std::bind2nd(std::mem_fun_ref(&BnId::setPI), 1));
+             std::bind(std::mem_fun_ref(&BnId::setPI), _1, 1));
 
     // Collect into pairs which have a difference of +/- one
     // object
@@ -951,8 +952,9 @@ It is set on exit (to the EPI)
     }
   }
   // Remove dead items from active list
+  using std::placeholders::_1;
   DNFactive.erase(remove_if(DNFactive.begin(), DNFactive.end(),
-                            std::bind2nd(std::less<int>(), 0)),
+                            std::bind(std::less<int>(), _1, 0)),
                   DNFactive.end());
 
   /// DEBUG PRINT
@@ -1515,8 +1517,9 @@ ab -> a'+b'
 */
 {
   Intersect = 1 - Intersect;
+  using std::placeholders::_1;
   transform(Units.begin(), Units.end(), Units.begin(),
-            std::bind2nd(std::multiplies<int>(), -1));
+            std::bind(std::multiplies<int>(), _1, -1));
   sort(Units.begin(), Units.end()); /// Resort the list. use reverse?
 
   for_each(Comp.begin(), Comp.end(), std::mem_fun_ref(&Acomp::complement));
diff --git a/Framework/Geometry/src/Math/BnId.cpp b/Framework/Geometry/src/Math/BnId.cpp
index c56f300daa95cf8390577dbb1a742c47091cf75f..f9a901804d17a544596cd3a7774950086b0d6f73 100644
--- a/Framework/Geometry/src/Math/BnId.cpp
+++ b/Framework/Geometry/src/Math/BnId.cpp
@@ -318,8 +318,9 @@ void BnId::reverse()
   Transform 1 -> -1
 */
 {
+  using std::placeholders::_1;
   transform(Tval.begin(), Tval.end(), Tval.begin(),
-            std::bind2nd(std::multiplies<int>(), -1));
+            std::bind(std::multiplies<int>(), _1, -1));
   setCounters();
 }
 
diff --git a/Framework/Geometry/src/Math/PolyBase.cpp b/Framework/Geometry/src/Math/PolyBase.cpp
index 70afb8d3fd36998d6d75c3f498cf9b442484a5cd..0b667e74b8db36218cdbfe83785234efc781db88 100644
--- a/Framework/Geometry/src/Math/PolyBase.cpp
+++ b/Framework/Geometry/src/Math/PolyBase.cpp
@@ -279,8 +279,9 @@ PolyBase &PolyBase::operator*=(const double V)
   @return (*this*V);
  */
 {
+  using std::placeholders::_1;
   transform(afCoeff.begin(), afCoeff.end(), afCoeff.begin(),
-            std::bind2nd(std::multiplies<double>(), V));
+            std::bind(std::multiplies<double>(), _1, V));
   return *this;
 }
 
@@ -291,8 +292,9 @@ PolyBase &PolyBase::operator/=(const double V)
   @return (*this/V);
  */
 {
+  using std::placeholders::_1;
   transform(afCoeff.begin(), afCoeff.end(), afCoeff.begin(),
-            std::bind2nd(std::divides<double>(), V));
+            std::bind(std::divides<double>(), _1, V));
   return *this;
 }
 
diff --git a/Framework/Geometry/src/Surfaces/LineIntersectVisit.cpp b/Framework/Geometry/src/Surfaces/LineIntersectVisit.cpp
index 53cb18a9d768d474fd19a99fc7d13f89a171bb6b..ad25cc8d4c395f4df138ada5a9f02fa78f7c9d52 100644
--- a/Framework/Geometry/src/Surfaces/LineIntersectVisit.cpp
+++ b/Framework/Geometry/src/Surfaces/LineIntersectVisit.cpp
@@ -107,8 +107,9 @@ void LineIntersectVisit::procTrack()
 {
   // Calculate the distances to the points
   DOut.resize(PtOut.size());
+  using std::placeholders::_1;
   std::transform(PtOut.begin(), PtOut.end(), DOut.begin(),
-                 boost::bind(&Kernel::V3D::distance, ATrack.getOrigin(), _1));
+                 std::bind(&Kernel::V3D::distance, ATrack.getOrigin(), _1));
 }
 
 } // namespace Geometry
diff --git a/Framework/Kernel/src/ConfigService.cpp b/Framework/Kernel/src/ConfigService.cpp
index a88cd8aeaa2fba38527793038fd5fc7290bca91e..8e95aa07b84dc9a915abe678ba5baacd67a8d1d9 100644
--- a/Framework/Kernel/src/ConfigService.cpp
+++ b/Framework/Kernel/src/ConfigService.cpp
@@ -618,9 +618,10 @@ bool ConfigServiceImpl::isInDataSearchList(const std::string &path) const {
   std::string correctedPath = path;
   replace(correctedPath.begin(), correctedPath.end(), '\\', '/');
 
+  using std::placeholders::_1;
   auto it =
       std::find_if(m_DataSearchDirs.cbegin(), m_DataSearchDirs.cend(),
-                   std::bind2nd(std::equal_to<std::string>(), correctedPath));
+                   std::bind(std::equal_to<std::string>(), _1, correctedPath));
   return (it != m_DataSearchDirs.end());
 }
 
diff --git a/Framework/Kernel/test/MatrixTest.h b/Framework/Kernel/test/MatrixTest.h
index 4607e1316e31e73402ce91c45968b824c56ab13d..dea93d9e0c1b89ab832f31522d42faddeafd6b05 100644
--- a/Framework/Kernel/test/MatrixTest.h
+++ b/Framework/Kernel/test/MatrixTest.h
@@ -141,8 +141,9 @@ public:
     X[2] = Eval[2][1];
 
     std::vector<double> out = A * X;
+    using std::placeholders::_1;
     transform(X.begin(), X.end(), X.begin(),
-              std::bind2nd(std::multiplies<double>(), Diag[1][1]));
+              std::bind(std::multiplies<double>(), _1, Diag[1][1]));
     TS_ASSERT_DELTA(X[0], out[0], 0.0001);
     TS_ASSERT_DELTA(X[1], out[1], 0.0001);
     TS_ASSERT_DELTA(X[2], out[2], 0.0001);
diff --git a/Framework/Nexus/src/NexusClasses.cpp b/Framework/Nexus/src/NexusClasses.cpp
index 68d13fcc916a6f0095ca011b25e35482ac191e70..180de52517a69951e0d66331bfb6303b9594dce1 100644
--- a/Framework/Nexus/src/NexusClasses.cpp
+++ b/Framework/Nexus/src/NexusClasses.cpp
@@ -650,8 +650,9 @@ Kernel::Property *NXLog::createTimeSeries(const std::string &start_time,
     times.load();
     std::string units = times.attributes("units");
     if (units == "minutes") {
+      using std::placeholders::_1;
       std::transform(times(), times() + times.dim0(), times(),
-                     std::bind2nd(std::multiplies<double>(), 60));
+                     std::bind(std::multiplies<double>(), _1, 60));
     } else if (!units.empty() && units.substr(0, 6) != "second") {
       return nullptr;
     }
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/Property.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/Property.cpp
index 0397ab6c77fc5baacb2e53a6afc08cd6b3a505a7..0a92e2ca101316ef37cd657f35936b8412fbf750 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Exports/Property.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/Property.cpp
@@ -29,6 +29,29 @@ using Mantid::Kernel::Property;
 using Mantid::PythonInterface::std_vector_exporter;
 using namespace boost::python;
 
+namespace {
+
+//
+// gcc 7 with std=c++17 has an issue attaching the EMPTY_*
+// functions with add_static_property when attempting to cast
+// the function pointer to a "const volatile void *":
+//
+//   arg_to_python.hpp:211:66: error: invalid conversion from 'double (*)()
+//   noexcept'
+//                             to 'const volatile void*' [-fpermissive]
+//
+// The noexcept specification appears to prevent the cast in the
+// boost python layer. These functions provide a pass through without the
+// noexcept specifier.
+
+constexpr inline double emptyDouble() { return Mantid::EMPTY_DBL(); }
+
+constexpr inline int emptyInt() { return Mantid::EMPTY_INT(); }
+
+constexpr inline long emptyLong() { return Mantid::EMPTY_LONG(); }
+
+} // namespace
+
 GET_POINTER_SPECIALIZATION(Property)
 GNU_DIAG_OFF("unused-local-typedef")
 // Ignore -Wconversion warnings coming from boost::python
@@ -116,7 +139,7 @@ void export_Property() {
                                   return_value_policy<return_by_value>()),
                     "Return the object managing this property's settings")
 
-      .add_static_property("EMPTY_DBL", &Mantid::EMPTY_DBL)
-      .add_static_property("EMPTY_INT", &Mantid::EMPTY_INT)
-      .add_static_property("EMPTY_LONG", &Mantid::EMPTY_LONG);
+      .add_static_property("EMPTY_DBL", emptyDouble)
+      .add_static_property("EMPTY_INT", emptyInt)
+      .add_static_property("EMPTY_LONG", emptyLong);
 }
diff --git a/buildconfig/CMake/SipQtTargetFunctions.cmake b/buildconfig/CMake/SipQtTargetFunctions.cmake
index 54cdd3bb6478b39f47d12bcb02d9cd6c8bae376b..e0fae82900f73235c5bb0c693d3513298dcb82c3 100644
--- a/buildconfig/CMake/SipQtTargetFunctions.cmake
+++ b/buildconfig/CMake/SipQtTargetFunctions.cmake
@@ -66,11 +66,12 @@ function ( mtd_add_sip_module )
   set ( _module_spec ${CMAKE_CURRENT_BINARY_DIR}/${PARSED_MODULE_NAME}.sip )
   configure_file ( ${_sipmodule_template_path} ${_module_spec} )
   set ( _pyqt_sip_dir ${PYQT${PARSED_PYQT_VERSION}_SIP_DIR} )
+  set ( _sip_wrapper ${CMAKE_SOURCE_DIR}/tools/sip/sipwrapper.py)
   list ( APPEND _sip_include_flags "-I${_pyqt_sip_dir}" )
   set ( _pyqt_sip_flags ${PYQT${PARSED_PYQT_VERSION}_SIP_FLAGS} )
   set ( _sip_generated_cpp ${CMAKE_CURRENT_BINARY_DIR}/sip${PARSED_MODULE_NAME}part0.cpp )
   add_custom_command ( OUTPUT ${_sip_generated_cpp}
-    COMMAND ${SIP_EXECUTABLE}
+    COMMAND ${PYTHON_EXECUTABLE} ${_sip_wrapper} ${SIP_EXECUTABLE}
       ${_sip_include_flags} ${_pyqt_sip_flags}
       -c ${CMAKE_CURRENT_BINARY_DIR} -j1 -w -e ${_module_spec}
     DEPENDS ${_module_spec} ${_sip_include_deps} ${SIP_INCLUDE_DIR}/sip.h
diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/QtMainWindowView.cpp b/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/QtMainWindowView.cpp
index 9db5f09b845415986a94b20bd617010d0f941a62..ae99ce4ac6464cb262f979a74e6a3bcf27978272 100644
--- a/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/QtMainWindowView.cpp
+++ b/qt/scientific_interfaces/ISISReflectometry/GUI/MainWindow/QtMainWindowView.cpp
@@ -79,9 +79,8 @@ void QtMainWindowView::initLayout() {
       {{"INTER", "SURF", "CRISP", "POLREF", "OFFSPEC"}});
 
   auto thetaTolerance = 0.01;
-  auto pythonRunner = this;
 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
-  Plotter plotter(pythonRunner);
+  Plotter plotter(this);
 #else
   Plotter plotter;
 #endif
@@ -90,9 +89,9 @@ void QtMainWindowView::initLayout() {
 
   auto defaultInstrumentIndex = getDefaultInstrumentIndex(instruments);
   auto messageHandler = this;
-  auto makeRunsPresenter = RunsPresenterFactory(
-      std::move(makeRunsTablePresenter), thetaTolerance, instruments,
-      defaultInstrumentIndex, messageHandler, pythonRunner);
+  auto makeRunsPresenter =
+      RunsPresenterFactory(std::move(makeRunsTablePresenter), thetaTolerance,
+                           instruments, defaultInstrumentIndex, messageHandler);
 
   auto makeEventPresenter = EventPresenterFactory();
   auto makeSaveSettingsPresenter = SavePresenterFactory();
diff --git a/qt/scientific_interfaces/ISISReflectometry/GUI/Runs/RunsPresenterFactory.h b/qt/scientific_interfaces/ISISReflectometry/GUI/Runs/RunsPresenterFactory.h
index b22b1077b9d7aeb1f283ec9f4cc20157a8125d28..23a73f39ef08ee3e957c06ed81a905e4aced22f7 100644
--- a/qt/scientific_interfaces/ISISReflectometry/GUI/Runs/RunsPresenterFactory.h
+++ b/qt/scientific_interfaces/ISISReflectometry/GUI/Runs/RunsPresenterFactory.h
@@ -23,13 +23,12 @@ public:
   RunsPresenterFactory( // cppcheck-suppress passedByValue
       RunsTablePresenterFactory runsTablePresenterFactory,
       double thetaTolerance, std::vector<std::string> instruments,
-      int defaultInstrumentIndex, IMessageHandler *messageHandler,
-      IPythonRunner *pythonRunner)
+      int defaultInstrumentIndex, IMessageHandler *messageHandler)
       : m_runsTablePresenterFactory(std::move(runsTablePresenterFactory)),
         m_thetaTolerance(std::move(thetaTolerance)),
         m_instruments(std::move(instruments)),
         m_defaultInstrumentIndex(std::move(defaultInstrumentIndex)),
-        m_messageHandler(messageHandler), m_pythonRunner(pythonRunner) {}
+        m_messageHandler(messageHandler) {}
 
   std::unique_ptr<IRunsPresenter> make(IRunsView *view) {
     return std::make_unique<RunsPresenter>(
@@ -43,7 +42,6 @@ private:
   std::vector<std::string> m_instruments;
   int m_defaultInstrumentIndex;
   IMessageHandler *m_messageHandler;
-  IPythonRunner *m_pythonRunner;
 };
 } // namespace ISISReflectometry
 } // namespace CustomInterfaces
diff --git a/qt/scientific_interfaces/ISISReflectometry/Reduction/Group.cpp b/qt/scientific_interfaces/ISISReflectometry/Reduction/Group.cpp
index 15e260f84af3baa422ca127acf8271e57d99af2f..1e6273de06f7194c8e4a11445f23303e0f809412 100644
--- a/qt/scientific_interfaces/ISISReflectometry/Reduction/Group.cpp
+++ b/qt/scientific_interfaces/ISISReflectometry/Reduction/Group.cpp
@@ -64,10 +64,9 @@ bool Group::requiresPostprocessing(bool reprocessFailed) const {
     return false;
 
   // If all rows are valid and complete then we're ready to postprocess
-  return std::all_of(m_rows.cbegin(), m_rows.cend(),
-                     [&reprocessFailed](boost::optional<Row> const &row) {
-                       return row && row->success();
-                     });
+  return std::all_of(
+      m_rows.cbegin(), m_rows.cend(),
+      [](boost::optional<Row> const &row) { return row && row->success(); });
 }
 
 std::string Group::postprocessedWorkspaceName() const {
diff --git a/qt/scientific_interfaces/ISISReflectometry/Reduction/Item.h b/qt/scientific_interfaces/ISISReflectometry/Reduction/Item.h
index f02ffca58d985199ce05ddad7430a91af255cc53..3cbb2d03951c5333e69f094e6f8eaaa34e9a687f 100644
--- a/qt/scientific_interfaces/ISISReflectometry/Reduction/Item.h
+++ b/qt/scientific_interfaces/ISISReflectometry/Reduction/Item.h
@@ -26,6 +26,7 @@ public:
   using ItemCountFunction = int (Item::*)() const;
 
   Item();
+  virtual ~Item() = default;
 
   virtual bool isGroup() const = 0;
   State state() const;
diff --git a/qt/widgets/mplcpp/src/Figure.cpp b/qt/widgets/mplcpp/src/Figure.cpp
index 462e12873c593de07ec4866c1694db6bf8edfc74..5ce49fcd6dbbe57d9363c7aad3cc41be2d4cc353 100644
--- a/qt/widgets/mplcpp/src/Figure.cpp
+++ b/qt/widgets/mplcpp/src/Figure.cpp
@@ -122,7 +122,7 @@ Python::Object Figure::colorbar(const ScalarMappable &mappable, const Axes &cax,
       Py_BuildValue("(OO)", mappable.pyobj().ptr(), cax.pyobj().ptr()));
   const auto kwargs = Python::NewRef(
       Py_BuildValue("{sOsO}", "ticks", ticks.ptr(), "format", format.ptr()));
-  Python::Object attr{pyobj().attr("colorbar")};
+  Python::Object attr(pyobj().attr("colorbar"));
   return Python::NewRef(PyObject_Call(attr.ptr(), args.ptr(), kwargs.ptr()));
 }
 
diff --git a/tools/sip/sipwrapper.py b/tools/sip/sipwrapper.py
new file mode 100755
index 0000000000000000000000000000000000000000..1ae794a8dcebdad1fd262e09fe97d617018b5c6c
--- /dev/null
+++ b/tools/sip/sipwrapper.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+# Mantid Repository : https://github.com/mantidproject/mantid
+#
+# Copyright &copy; 2019 ISIS Rutherford Appleton Laboratory UKRI,
+#     NScD Oak Ridge National Laboratory, European Spallation Source
+#     & Institut Laue - Langevin
+# SPDX - License - Identifier: GPL - 3.0 +
+"""
+Wraps a call to the sip code generation executable to strip any throw specifications
+from the generated code as these have been removed from C++17.
+"""
+from __future__ import (absolute_import, division, print_function, unicode_literals)
+
+# system imports
+import argparse
+import logging
+import os
+import re
+import subprocess
+import sys
+
+LOG_LEVEL = logging.INFO
+EXTENSION = '.cpp'
+GENERATED_FILENAME_TEMPLATE = 'sip{modulename:s}part0{extension:s}'
+THROW_SPEC_RE = re.compile(r'throw\(.*?\)')
+
+
+def main(argv):
+    """
+    Main entry point for the program.
+
+    :param argv: Command-line arguments. The first
+    argument is expected to be full path to the sip
+    program. Any subsequent arguments are passed
+    directly to sip invocation
+    """
+    configure_logging()
+    sip_cmd_line, spec_file, output_dir = parse_arguments(argv)
+    logging.debug("Processing specification: {}".format(spec_file))
+
+    run_vanilla_sip(sip_cmd_line)
+    generated_module_path = generated_filepath(output_dir, spec_file)
+    if not os.path.exists(generated_module_path):
+        raise RuntimeError("Unable to find sip-generated module '{}'".format(generated_module_path))
+    logging.debug("Found generated module: {}".format(generated_module_path))
+
+    sanitize_generated_module(generated_module_path)
+    return 0
+
+
+def configure_logging():
+    """
+    Configure the logging framework
+    """
+    logging.basicConfig(level=LOG_LEVEL)
+
+
+def parse_arguments(argv):
+    """
+    Process command-line arguments and extract
+    the output directory
+    :return: A 4-tuple (sip_cmd, path to spec file, output directory, nparts)
+    """
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-c', dest='output_dir')
+    known_args, _ = parser.parse_known_args(argv)
+    sip_cmd_line = argv[1:]
+    if sys.platform == 'win32':
+        sip_cmd_line = map(lambda s: s.replace('\\', '\\\\'), sip_cmd_line)
+        # the executable may need .exe appending to be run with the cmd
+        # processor
+        sip_exe = sip_cmd_line[0] + '.exe'
+        if os.path.exists(sip_exe):
+            sip_cmd_line[0] = sip_exe
+
+    spec_file = argv[-1]
+
+    return sip_cmd_line, spec_file, known_args.output_dir
+
+
+def run_vanilla_sip(sip_cmd_line):
+    """
+    Run unmodified sip command to produce the initial .cpp module
+
+    :param sip_cmd: The full sip command as passed to this program
+    :raises: RuntimeError if the sip command fails
+    """
+    logging.debug("Running sip: {}".format(' '.join(sip_cmd_line)))
+    retcode = subprocess.call(sip_cmd_line)
+    if retcode != 0:
+        raise RuntimeError("Error running sip.")
+
+
+def generated_filepath(output_dir, spec_filename):
+    """
+    Compute the path of the sip-generated module file.
+    :param output_dir: The directory the output has been placed in.
+    :param specfile: The original specfilename
+    :return: The full path to the generated file
+    """
+    modulename, _ = os.path.splitext(os.path.basename(spec_filename))
+    return os.path.join(
+        output_dir, GENERATED_FILENAME_TEMPLATE.format(modulename=modulename, extension=EXTENSION))
+
+
+def sanitize_generated_module(generated_module_filepath):
+    """
+    Takes the module code as generated by sip and sanitizes it to be compatible
+    with the current standard. It replaces the original file.
+
+    Currently:
+      - removes all throw() specifications as they are not supported in C++ 17
+
+    :param generated_module_filepath:
+    """
+    with open(generated_module_filepath, 'r') as sip_module_orig:
+        module_code_orig = sip_module_orig.readlines()
+
+    sanitized_code = []
+    for line_orig in module_code_orig:
+        sanitized_code.append(THROW_SPEC_RE.sub('', line_orig))
+
+    with open(generated_module_filepath, 'w') as sanitized_module:
+        sanitized_module.write(''.join(sanitized_code))
+
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))