mem_fun + bind2nd允许调用具有任意类型参数的方法

时间:2017-09-08 10:02:24

标签: c++ bind

考虑这个例子(https://ideone.com/RpFRTZ

这将有效地使用不相关类型Foo::comp (const Foo& a)的参数调用Bar。 这不仅会编译,如果我注释掉std::cout << "a = " << a.s << std::endl;它也会以某种方式工作并打印Result: 0

如果我确实打印出了值,而不是段错误,这是公平的......但为什么它首先编译?

#include <functional>
#include <string>
#include <iostream>

struct Foo
{
    bool comp(const Foo& a)
    {
        std::cout << "a = " << a.s << std::endl;
        return a.s == s;
    }

    std::string s;

};

struct Bar
{
    int a;
};


template <class F, class T>
void execute (F f, T a)
{
    std::cout << "Result: " << f (a) << std::endl;

}

int main()
{
    Foo* f1 = new Foo;
    f1->s = "Hello";

    Foo f2;
    f2.s = "Bla";

    Bar b;
    b.a = 100;

    execute (std::bind2nd (std::mem_fun(&Foo::comp), b), f1);


    return 0;
}

1 个答案:

答案 0 :(得分:1)

答案在于std :: bind2nd:

的实现
package com.example.mi.mikpiadmin;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;

public class Store_KPI extends AppCompatActivity implements ListView.OnItemClickListener {
    private PreferenceHelper preferenceHelper;
    ListView listView1;
    public static final String URL_GET_ISSUE = "http://dcoder.in/mi/two.php";

    public static final String TAG_JSON_ARRAY="result";
    public static final String TAG_ID = "id";
    public static final String TAG_PARAMETER = "parameter";
    public static final String TAG_ACHIEVEMENT = "achievement";
    public static final String TAG_TARGET_WEEKLY = "target_weekly";
    public static final String TAG_TARGET_MONTHLY = "target_monthly";
    public static final String TAG_PER_ACHIEVEMENT = "per_achievement";


    private String JSON_ISSUE_STRING;
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_store_kpi);
      preferenceHelper = new PreferenceHelper(this);
        listView1=(ListView)findViewById(R.id.list_view_store_kpi) ;
        listView1.setOnItemClickListener(this);
        getJSON();

    }


    private void showEmployee(){
        JSONObject jsonObject = null;
        ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String, String>>();
        try {
            jsonObject = new JSONObject(JSON_ISSUE_STRING);
            JSONArray result = jsonObject.getJSONArray(TAG_JSON_ARRAY);

            for(int i = 0; i<result.length(); i++){
                JSONObject jo = result.getJSONObject(i);
                String parameter = jo.getString(TAG_PARAMETER);
                String achievement = jo.getString(TAG_ACHIEVEMENT);
                String target = jo.getString(TAG_TARGET_WEEKLY);
                String mtarget = jo.getString(TAG_TARGET_MONTHLY);
                String per_achievement = jo.getString(TAG_PER_ACHIEVEMENT);

                HashMap<String,String> employees = new HashMap<>();
                employees.put(TAG_PARAMETER,parameter);
                employees.put(TAG_ACHIEVEMENT,achievement);
                employees.put(TAG_TARGET_WEEKLY,target);
                employees.put(TAG_TARGET_MONTHLY,mtarget);
                employees.put(TAG_PER_ACHIEVEMENT,per_achievement);
                list.add(employees);

            }

        } catch (JSONException e) {
            e.printStackTrace();
        }

        ListAdapter adapter = new SimpleAdapter(
                Store_KPI.this, list, R.layout.list_item,
                new String[]{TAG_PARAMETER,TAG_ACHIEVEMENT,TAG_TARGET_WEEKLY,TAG_TARGET_MONTHLY,TAG_PER_ACHIEVEMENT},
                new int[]{R.id.id, R.id.name, R.id.feedback,R.id.parmeter,R.id.target});
        listView1.setAdapter(adapter);
        ((SimpleAdapter) listView1.getAdapter()).notifyDataSetChanged();

    }


    private void getJSON(){
        class GetJSON extends AsyncTask<Void,Void,String> {

            private ProgressDialog loading;
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                loading = ProgressDialog.show(Store_KPI.this,"Fetching Data","Wait...",false,false);
            }

            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                loading.dismiss();
                JSON_ISSUE_STRING = s;
                showEmployee();
            }

            @Override
            protected String doInBackground(Void... params) {
                RequestHandler rh = new RequestHandler();
                String s  = rh.sendGetRequest(URL_GET_ISSUE+"?store="+preferenceHelper.getStore());

                Log.d("123",s);
                return s;
            }
        }
        GetJSON gj = new GetJSON();
        gj.execute();
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        Intent intent = new Intent(this, Store_KPI.class);
        HashMap<String,String> map =(HashMap)parent.getItemAtPosition(position);

        //String empId = map.get(Config.TAG_ID).toString();
        //intent.putExtra(Config.EMP_ID,empId);
        startActivity(intent);
    }


}


Logcat
09-11 12:41:57.852 30353-30353/? D/AndroidRuntime: Calling main entry com.android.commands.pm.Pm
09-11 12:41:57.860 30353-30363/? W/MessageQueue: Handler (android.os.Handler) {bda2ab} sending message to a Handler on a dead thread
                                                 java.lang.IllegalStateException: Handler (android.os.Handler) {bda2ab} sending message to a Handler on a dead thread
                                                     at android.os.MessageQueue.enqueueMessage(MessageQueue.java:543)
                                                     at android.os.Handler.enqueueMessage(Handler.java:643)
                                                     at android.os.Handler.sendMessageAtTime(Handler.java:612)
                                                     at android.os.Handler.sendMessageDelayed(Handler.java:582)
                                                     at android.os.Handler.post(Handler.java:338)
                                                     at android.os.ResultReceiver$MyResultReceiver.send(ResultReceiver.java:57)
                                                     at com.android.internal.os.IResultReceiver$Stub.onTransact(IResultReceiver.java:58)
                                                     at android.os.Binder.execTransact(Binder.java:565)
09-11 12:41:57.861 30353-30353/? I/art: System.exit called, status: 0
09-11 12:41:57.861 30353-30353/? I/AndroidRuntime: VM exiting with result code 0.
09-11 12:43:26.885 1579-1586/? I/art: Background sticky concurrent mark sweep GC freed 25454(2MB) AllocSpace objects, 2(136KB) LOS objects, 16% free, 14MB/17MB, paused 2.151ms total 142.176ms
09-11 12:46:48.997 1355-1573/? D/MDnsDS: MDnsSdListener::Monitor poll timed out
09-11 12:46:48.997 1355-1573/? D/MDnsDS: Going to poll with pollCount 1

                                         --------- beginning of system
09-11 12:46:56.827 1579-1628/? D/ConnectivityService: NetworkAgentInfo [MOBILE (LTE) - 100] validation failed
09-11 12:50:54.788 1579-1586/? I/art: Background sticky concurrent mark sweep GC freed 30451(3MB) AllocSpace objects, 4(224KB) LOS objects, 19% free, 13MB/17MB, paused 1.593ms total 146.983ms
09-11 12:58:17.038 1579-1628/? D/ConnectivityService: NetworkAgentInfo [MOBILE (LTE) - 100] validation failed
09-11 13:00:02.319 1579-1624/? D/WifiNative-HAL: Failing getSupportedFeatureset because HAL isn't started
09-11 13:00:02.320 1579-1595/? E/BluetoothAdapter: Bluetooth binder is null
09-11 13:00:02.320 1579-1595/? E/BatteryStatsService: no controller energy info supplied
09-11 13:00:02.322 1579-1595/? E/KernelCpuSpeedReader: Failed to read cpu-freq: /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state (No such file or directory)
09-11 13:00:02.322 1579-1595/? E/KernelUidCpuTimeReader: Failed to read uid_cputime: /proc/uid_cputime/show_uid_stat (No such file or directory)
09-11 13:00:02.323 1579-1595/? E/BatteryStatsService: modem info is invalid: ModemActivityInfo{ mTimestamp=0 mSleepTimeMs=0 mIdleTimeMs=0 mTxTimeMs[]=[0, 0, 0, 0, 0] mRxTimeMs=0 mEnergyUsed=0}
09-11 13:00:12.608 1579-1579/? I/EntropyMixer: Writing entropy...
09-11 13:00:51.190 23018-23055/? D/EGL_emulation: eglMakeCurrent: 0xaab05720: ver 2 0 (tinfo 0xaab03740)
09-11 13:00:51.399 1579-1613/? I/ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.android.launcher3/.Launcher (has extras)} from uid 1000 on display 0
09-11 13:00:51.400 1346-1369/? W/audio_hw_generic: Not supplying enough data to HAL, expected position 2278264 , only wrote 2278080
09-11 13:00:51.424 1304-1338/? D/gralloc_ranchu: gralloc_alloc: Creating ashmem region of size 2650112


                                                 [ 09-11 13:00:51.432  1579: 1613 D/         ]
                                                 HostConnection::get() New Host Connection established 0x9a6e7d40, tid 1613


                                                 [ 09-11 13:00:51.433  1579: 1613 W/         ]
                                                 Unrecognized GLES max version string in extensions: ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_dma_v1 
09-11 13:00:51.467 27945-27974/? D/EGL_emulation: eglMakeCurrent: 0xa8270320: ver 2 0 (tinfo 0xa820a7e0)
09-11 13:00:51.592 1985-2257/? D/EGL_emulation: eglMakeCurrent: 0xaab05480: ver 2 0 (tinfo 0xaab03660)
09-11 13:00:52.091 1985-2257/? W/OpenGLRenderer: Incorrectly called buildLayer on View: ShortcutAndWidgetContainer, destroying layer...
09-11 13:00:54.627 1346-1370/? W/audio_hw_generic: Not supplying enough data to HAL, expected position 2585797 , only wrote 2432880
09-11 13:01:00.022 23018-23055/? D/EGL_emulation: eglMakeCurrent: 0xaab05720: ver 2 0 (tinfo 0xaab03740)
09-11 13:01:00.049 1579-1592/? I/ProcessStatsService: Prepared write state in 7ms
09-11 13:01:00.073 1579-1591/? I/ProcessStatsService: Pruning old procstats: /data/system/procstats/state-2017-09-07-13-05-30.bin

你可以看到有一种不安全的C风格演员&#34; _Arg2_type(__ x)&#34;到了正确的类型,所以你的例子就像编写它一样编译:

  template<typename _Operation, typename _Tp>
    inline binder2nd<_Operation>
    bind2nd(const _Operation& __fn, const _Tp& __x)
    {
      typedef typename _Operation::second_argument_type _Arg2_type;
      return binder2nd<_Operation>(__fn, _Arg2_type(__x));
    }

,遗憾的是有效的C ++代码。