Lyn
조회 수 172 추천 수 0 댓글 0

"비밀글입니다."


Lyn
조회 수 27902 추천 수 0 댓글 0
Atachment
첨부 '2'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

Cilk plus 자료와 Sample Code

?

Lyn
조회 수 21723 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
iisreset 
?

?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

권한을 줄 아이디를 입력할 때 

IIS AppPool\[풀 이름] 


처럼 하면 권한을 줄 아이디가 나타난다

?

Lyn
조회 수 3277 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

type in console : Diskperf -Y

 

restart task manager

?

Lyn
조회 수 2199 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

lastest nginx for ubuntu 14.04 compile with older version openssl then not support ALPN.

Unfortunately, chrome is not support http2+NPN, only support http2+ALPN. 

require recompile nginx with new version openssl

 

Original : https://alex.bouma.me/recompile-nginx-with-openssl-1-0-2-for-http-2-via-alpn-ubuntu-14-04/

 

# Install package building tools
sudo apt-get install -y dpkg-dev

# (optional) cleanup previous work directory
#sudo rm -R /opt/nginx

# Create a work directory
sudo mkdir /opt/nginx

# Switch to our work directory
cd /opt/nginx

# Get NGINX source files
sudo apt-get source nginx

# Install NIGNX build dependencies
sudo apt-get -y build-dep nginx

# Switch to the source files directory
# You might need to change the version number in your case
cd nginx-1.*

# Build the .deb package files
sudo dpkg-buildpackage -b

# Move back to out work directory where the .deb files are placed
cd /opt/nginx

# Stop NGINX
sudo service nginx stop

# Install the newly build .deb file
sudo dpkg --install nginx_1.*~trusty_amd64.deb

# Start NGINX
sudo service nginx start

?

Lyn
조회 수 818 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

Original : https://intellij-support.jetbrains.com/hc/en-us/articles/206544879-selecting-the-jdk-version-the-ide-will-run-under?page=3

 

 

Windows

JDK (JetBrains Runtime) is bundled with all the product installers and it's recommended that you will use the provided JDK version unless there are any specific issues. Since 2017.1 version 64-bit JDK is bundled by default on all the systems (32-bit JDK can be downloaded on Windows by the installer if needed).

JetBrains Runtime (based on OpenJDK) can be also downloaded separately, but you normally don't need to do it. 

<product>.exe uses this JDK search sequence:

  1. IDEA_JDK / PHPSTORM_JDK / WEBIDE_JDK / PYCHARM_JDK / RUBYMINE_JDK / CLION_JDK / DATAGRIP_JDK environment variable (depends on the product, WEBIDE_JDK applies to both WebStorm and PhpStorm before version 2016.1)

  2. idea.config.path\<product>.jdk file
  3. ..\jre directory
  4. system Registry
  5. JDK_HOME environment variable
  6. JAVA_HOME environment variable

<product>64.exe uses this JDK search sequence:

  1. IDEA_JDK_64/ PHPSTORM_JDK_64 / WEBIDE_JDK_64 / PYCHARM_JDK_64 / RUBYMINE_JDK_64 / CLION_JDK_64 / DATAGRIP_JDK_64 environment variable
  2. idea.config.path\<product>64.jdk file
  3. ..\jre64 directory
  4. system Registry
  5. JDK_HOME environment variable
  6. JAVA_HOME environment variable

It’s also possible to start the IDE with <product>.bat file located in the bindirectory, it uses the following JDK search sequence:

  1. IDEA_JDK / PHPSTORM_JDK / WEBIDE_JDK / PYCHARM_JDK / RUBYMINE_JDK / CLION_JDK / DATAGRIP_JDK environment variable (depends on the product)
  2. idea.config.path\<product>64.jdk file
  3. idea.config.path\<product>.jdk file
  4. ..\jre64 directory
  5. ..\jre directory
  6. JDK_HOME environment variable
  7. JAVA_HOME environment variable
Environment variable must point to the JDK installation home directory, for example:
c:\Program Files (x86)\Java\jdk1.8.0_112
  • The actual JDK version used by the IDE can be verified in Help | Aboutdialog (open any project to access the menu).
  • Define IDEA_JDK / PHPSTORM_JDK / WEBIDE_JDK / PYCHARM_JDK / RUBYMINE_JDK/ CLION_JDK / DATAGRIP_JDK variable depending on the product to override the default version from IDE_HOME\jre.
  • Use Rapid Environment Editor to add/edit the variables, it will detect incorrect paths.
?

Lyn
조회 수 39300 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Non-ASCII_Characters


번역중


헤더파일

  - 중복방지를 위한 헤더가드 : 모든 헤더는 중복 include 를 막기 위한 헤더가드를 가진다. 이는 <PROJECT>_<PATH>_<FILE>_H_ 의 포맷으로 만들어져있어야 한다

  - 헤더파일 의존성 : 번역중

  - 인라인 함수 : 10줄 혹은 그보다 작은 함수에만 사용한다.

  - -ini.h 파일 : 복잡한 인라인함수를 만들어야 할 때 ~ini.h 형태를 사용한다

  - 함수 파라메터 순서 : 함수 파라메터는 입력파라메터가 출력 파라메터보다 먼저 온다



?

Lyn
조회 수 3632 추천 수 0 댓글 0
Atachment
첨부 '4'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

네. 요즘 고해상도 디스플레이(맥북 프로 레티나 라거나, 4K 모니터 라거나, 아니면 Razer Blade나 Aorus X3 Plus 같은) 디바이스가 꽤 늘어 났습니다.

이런놈들 말이죠


dpi3.png


dpi4.png






하지만 윈도는 고해상도 지원 꽤 느린편이어서 Vista 부터 일단 지원은 햇지만 거의 쓰이지 않았고 본격적인 지원은 역시 8 부터라고 보이는데요. 뭐 사실 윈도 7이 나온 2009년보다도 한참 지난 2012년 맥북 프로 레티나 부터 PC/랩탑용 고해상도 디스플레이가 등장 했으니 그러려니 합니다.


어쨋든 중요한건 이제 저런 장비를 쓰는 사람들도 있고 하니 고 DPI 지원을 해야 한다는거겠지요.
그러려면 DPI 를 가져와야 하는데 그 방법중 하나인 Direct2D 를 이용한 방법을 간단히 정리 해 둡니다.


개발자 답게 코드부터 보자면 

#include <iostream>
#include <D2d1.h>

using namespace std;

#pragma comment(lib, "D2d1.lib")

void wmain()
{
    ID2D1Factory* pD2DFactory = nullptr;
    if (SUCCEEDED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory)))
    {
        float dpix, dpiy;
        pD2DFactory->ReloadSystemMetrics();
        pD2DFactory->GetDesktopDpi(&dpix, &dpiy);
        pD2DFactory->Release();

        wcout << L"X : " << dpix << endl << L"Y : " << dpiy << endl;
    }
    else
    {
        wcout << L"Direct 2D Create Error";
    }    
}

라는 대단히 심플 한 코드로 가져올 수 있습니다.

D2D 팩토리를 생성후 ReloadSystemMetrics 호출 후 GetDesktopDpi 를 통해서 가져오는 매우 심플한 방식인데, ReloadSystemMetrics  를 하지 않으면 팩토리 생성 후 변화된 Dpi 설정을 가져오지 못합니다(내부에서 캐시하는듯)


dpi1.png




위와 같은 실행 결과가 나옵니다. 윈도우의 기본 DPI(100%) 값은 96 으로서 이는 23인치 FullHD에 맞도록 세팅 된 값입니다(사실 "현재까지 쓰인 일반적인" 모니터의 크기와 해상도라면 대부분 매칭 됩니다. 17인치 1280*1024 도 96DPI 입니다)

그럼 125%로 바꿔서 한번 테스트 해 보겠습니다.

dpi2.png


 

네. 96 * 1.25 = 120 이니까 정확히 나오네요.

 

당연하겠지만 Direct2D 를 사용 한 방식이므로 Windows Vista Sp2 or Higher 를 요구합니다.

TAG •
?

Lyn
조회 수 4095 추천 수 0 댓글 0
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

3월 28일 업데이트 된 364.72 버전 Geforce 드라이버에서는 Vulkan 이 공식 지원됩니다.

또한 vulkan 지원 정보를 간략히 볼 수 있는 SW인 vulkaninfo 가 같이 설치됩니다

 

vul.PNG

 

?

Lyn
조회 수 2408 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

add compile option flag /d2Zi+

 

맨날 까먹어서 저장용으로

?

Lyn
조회 수 25058 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

DLLMain은 WinMain 이나 main 과는 다르게 제약이 많다.

나도 이걸로 크래시 낸 적이 많이몇번 있고 ... 


DLLMain은 일종의 "객체의생성자" 라고 보면 비슷하다.

"로딩중" 인 것이지 로딩이 끝난것이 아니다 라는것이다.


아래에는 Attach 시 기준으로 적었지만, Detach 에도 별 다를건 없다. kerner32.dll 이외의 dll은 이미 언로딩 되어있을 수도 있다.


이제 하지 말아야할것을 슬~슬 나열 해 보자. 


1. kernel32.dll 이외의 dll에 있는 함수 대부분.

kernel32.dll 이외의 dll이 로딩되어 있다는 보장은 전혀없다


2. 동기화코드

락, 언락 등의 코드


3. LoadLibrary, CreateProcess

다른 DLL 쓰지말라는말과 일맥상통. 


4. 전역객체 초기화, 메모리할당 등

메모리메니저가 로딩되었다는 보장이 없다


5. COM관련 코드

역시 보장없다


6. 예외 throw

C++ 객체 생성자에서 throw 하는것과 비슷한 대략므흣한 (...) 상황이 발생한다.


결론. 

DLLMain은 걍 비워 둬라. 그리고 Initialize 함수를 제공해라.
상당수의 라이브러리가 라이브러리 초기화 함수를 제공하는것은 다 이유가 있다!

(당장 GDI+와 Winsock2를 생각해봐라!) 

?

Lyn
조회 수 2354 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

윈도 10을 쓰고 있다가 어느날 게임을 하려는데 그래픽드라이버에 문제가 있는것을 발견했습니다.

그래서 드라이버를 다운그레이드 했는데... 이 빌어먹을 윈도 업데이트가 자동으로 드라이버를 올려버리는겁니다 (...)

그래서 방법을 찾다보니, 아래와 같은 툴을 MS가 제공 하고 있습니다.

드라이버 업데이트를 선택적으로 끌 수 있게 되어 있네요.

 

.. 다행입니다.

 

https://support.microsoft.com/en-us/kb/3073930

TAG •
?

Lyn
조회 수 38867 추천 수 0 댓글 1
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

Delphi 2009(Win32) 에서 추가된 Generics 에 관해서 간략하게 써 보겠습니다.

 

Generic 이란 임의의 타입에 대해 동작하는 매소드(클래스) 를 만드는 방법으로, C++에서는 Template이라 불리며 C#, Java 등에서는 Generics 라 불리는 기능이며, 일반화 프로그래밍을 가능하게 해주는 방법입니다.

 

간단한 예제를 하나 만들어 보겠습니다

변수의 크기를 출력하는 간단한 예제입니다.

 

 

program Project1;

 

{$APPTYPE CONSOLE}

 

uses

  SysUtils, VarUtils;

 

type

  TempClass = Class

  public

    procedure GetSize<T>(Item : T);

  end;

 

  TempRecord = packed Record

    A : Integer;

    B : Double;

    C : Double;

  End;

 

procedure TempClass.GetSize<T>(Item : T);

begin

  WriteLn('Size : ', Sizeof(Item));

End;

 

var

  A : TempClass;

  B : Integer;

  C : TempRecord;

begin

  A.GetSize(3000);

  A.GetSize(4.0);

 

  B := 30;

  A.GetSize(B);

 

  A.GetSize(C);

  ReadLn;

end.

 

 

결과는 각각

2, 10, 4, 20 이 나옵니다.

 

여기서 즉 T 이라는 임의의 Type 에 관해서 크기를 알아 올 수 있는겁니다.

 

여기서 어떻게 Type 이 지정 되냐를 알 수 있는데.

3000을 넘었을 경우는 2byte 정수형 으로 인정한 것을 알 수 있습니다.

 

정수형의 경우는 입력한 숫자의 크기에 따라 1~8 byte 정수형으로 함수가 생성 됩니다.

4.0을 넣었을 경우는 크기가 10이 나왔는데, 모든 실수형은 Extended 형으로 생성합니다.

 

Integer형의 변수 B를 넣었을 경우는 이미 타입이 Integer  라는 것을 명시적으로 선언 하였으므로 크기는 4Byte 가 됩니다.

 

TempRecord 형의 변수는 당연히 20Byte가 나옵니다(Integer + Double + Double)

 

이처럼 하나의 함수로 다양한 Type 에 대한 계산이 가능해 집니다.

 

이것은 컴파일 시점에 GetSize 라는 함수를 프로그래머가 사용한 Type 에 따라 여러벌 만들기에 가능한 것입니다.

 

디스어셈블한 코드를 구경 해보도록 하겠습니다

Project1.dpr.22: WriteLn('Size : ', Sizeof(Item));

0040E1BB A1980A4100       mov eax,[$00410a98]

0040E1C0 BAF0E14000       mov edx,$0040e1f0

0040E1C5 E86A73FFFF       call @Write0UString

0040E1CA BA0A000000       mov edx,$0000000a

0040E1CF E89856FFFF       call @Write0Long

0040E1D4 E8BF56FFFF       call @WriteLn

0040E1D9 E8724DFFFF       call @_IOTest
Project1.dpr.22: WriteLn('Size : ', Sizeof(Item));

0040E200 A1980A4100       mov eax,[$00410a98]

0040E205 BA30E24000       mov edx,$0040e230

0040E20A E82573FFFF       call @Write0UString

0040E20F BA04000000       mov edx,$00000004

0040E214 E85356FFFF       call @Write0Long

0040E219 E87A56FFFF       call @WriteLn

0040E21E E82D4DFFFF       call @_IOTest

Project1.dpr.22: WriteLn('Size : ', Sizeof(Item));

0040E240 A1980A4100       mov eax,[$00410a98]

0040E245 BA70E24000       mov edx,$0040e270

0040E24A E8E572FFFF       call @Write0UString

0040E24F BA14000000       mov edx,$00000014

0040E254 E81356FFFF       call @Write0Long

0040E259 E83A56FFFF       call @WriteLn

0040E25E E8ED4CFFFF       call @_IOTest

 

 

이와 같이 같은 이름의 함수가 비슷비슷한 코드로 여러벌 생성 되어 메모리에 들어있는 것을 확인 할 수 잇습니다.

 

 

이번엔 Type 을 명시적으로 알려주는 코드를 보도록 하겠습니다.

A.GetSize(3); 의 호출 결과는 1이었습니다.

숫자가 작기떄문에 최대한 작은 크기의 메모리를 소모 하기 위하여 Byte 형으로 선언 된 결과입니다.

 

그런데 간혹 정해진 Type 이 필요 할 수도 있습니다.

이럴경우 Type 을 명시적으로 지정해서 호출 해 보겠습니다.

 

A.GetSize<Integer>(3);

로 코드를 변경 한 후 호출하면 4가 출력 되는 것을 알 수 있습니다.

 

무조건 Integer 형의 함수를 호출 하라는 일종의 협박(?) 비슷한 코드를 만들어 낸 셈이 되는겁니다.

 

 

 

다음으로 알아 볼 것은 모든 알고리즘이 임의의 타입에 대해 동작 될 수 없는 경우에 관한 해결책입니다.

 

위의 코드에서 Integer, Double, Record 형의 크기는 아무 문제 없이 구할 수 있었지만, String 형의 크기는 sizeof() 연산자로 구할 수 없습니다.

 

이럴경우 String에 관해서만 특별한 처리를 해 주어야 하는데이는 익히 잘 아시는 오버로딩을 응용하면 됩니다.

 

예제코드를 보겠습니다.

program Project1;

 

{$APPTYPE CONSOLE}

 

uses

  SysUtils, VarUtils;

 

type

  TempClass = Class

  public

    procedure GetSize(Item : String); overload;

    procedure GetSize<T>(Item : T); overload;

  end;

 

  TempRecord = packed Record

    A : Integer;

    B : Double;

    C : Double;

  End;

 

procedure TempClass.GetSize<T>(Item : T);

begin

  WriteLn('Size : ', Sizeof(Item));

End;

 

procedure TempClass.GetSize(Item : String);

begin

  WriteLn('Size : ', Length(Item));

End;

 

var

  A : TempClass;

  B : Integer;

  C : TempRecord;

begin

  A.GetSize<Integer>(3);

  A.GetSize(4.0);

 

  B := 30;

  A.GetSize(B);

 

  A.GetSize(C);

  A.GetSize('Hello Delphi!');

  ReadLn;

end.

 

GetSize 매소드를 T 형과 String 형에 관해 각각 오버로딩 하엿습니다.

String 형으로 GetSize 를 호출하면 Length 를 호출해서 계산하는 함수가, 다른 형으로 GetSize를 호출하면 Sizeof 를 사용하는 함수가 호출 됩니다.

 

이처럼 특정한 Type 에 관해 매소드를 다른 형태로 사용 할 수 있습니다.

 

 

지금까지는 함수의 Generic 을 살펴 보았습니다. 이제 클래스에 관한 Generic 을 살펴 보도록 하겠습니다.

 

program Project1;

 

{$APPTYPE CONSOLE}

 

uses

  SysUtils, VarUtils;

 

type

  TempClass<T> = Class

  public

    Item : T;

  end;

 

  TempRecord = packed Record

    A : Integer;

    B : Double;

    C : Double;

  End;

 

var

  A : TempClass<String>;

  B : TempClass<Integer>;

  C : TempClass<TempRecord>;

begin

  A := TempClass<String>.Create;

  A.Item := 'Hello RAD Studio!';

 

  B := TempClass<Integer>.Create;

  B.Item := 512;

 

  C := TempClass<TempRecord>.Create;

  C.Item.A := 55805096;

  C.Item.B := 3.14159;

  C.Item.C := 0.0;

  ReadLn;

end.

 

위 코드에서는 T 라는 임의의 타입을 가지는 클래스 TempClass<T> 를 선언하엿습니다.

그리고 각각 : String, Integer, TempRecord 형을 가지는 클래스 TempClass<String>. TempClass<Integer>, TempClass<TempRecord> 를 선언 하엿습니다 (TempClass<타입명> 까지가 클래스 이름이라고 생각하시면 편합니다)

 

그리고 각각의 클래스를 생성하고 Item 변수에 접근하여 값을 넣었습니다.

선언한 형태에 따라 TempClass 는 여러 타입의 Item 을 가지는 클래스로 탄생합니다.

 

TIntegerList, TDoubleList 등등을 따로 제작 할 필요 없이 임의의 타입을 가지는 콜렉션을 만들어 쓸 수 있습니다. 사실 이게 Generic을 쓰는 가장 큰 이유라고도 할 수 있습니다. Generic 으로 콜렉션을 만들면 캐스팅이 필요 없고, 타입이 명확하기 때문에 편리하게 사용 할 수 있습니다.

(.net Dictionary<> , STL Vactor<>, List<>, MFC CArray<,> 등이 그에 해당합니다)

마지막으로 한가지만 더 보도록 하겠습니다.

program Project1;

 

{$APPTYPE CONSOLE}

 

uses

  SysUtils, VarUtils;

 

type

  TempClass<T1, T2> = Class

  public

    Item1 : T1;

    Item2 : T2

  end;

 

var

  A : TempClass<String, Integer>;

begin

  A := TempClass<String, Integer>.Create;

  A.Item1 := 'Hello RAD Studio!';

  A.Item2 := 3;

 

  ReadLn;

end.

 

임의의 Type 은 반드시 한 개여야 한다는 제약은 없습니다.

여러 개의 임의의 Type 을 가지는 클래스도 얼마든지 선언 가능합니다.

 

위 코드는 2개의 임의의 Type을 가지는 TempClass<,> 를 선언, 사용 한 모습입니다.

 

 

PS. 간단한 함수도 매소드로 만들어서 예제를 구성했는데... 제가 잘 못해서 그런건진 모르겠는데, 델파이의 제네릭은 전역함수의 제네릭화를 허용 하지 않는 것 같습니다.

 

----

?
  • ?
    GomSun2 2010.06.17 19:54

    와우 좋은 강좌 잘봣음. :)


Lyn
조회 수 40872 추천 수 0 댓글 1
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

- 2010.1.3 지금 이걸 계속 써야 하나 말아야하나 고민중이다. 단돈 몇만원이 아까운게 아니라면 Beyond Compare 사서 써라. 진리다. 비교할 의미자체를 모르겠다(단. 3Way Marge 는 내가 쓰지 않아 잘 모른다)

  2011.11.22 2년사이에 많이 바뀌어서 내용을 추가


[파일비교]

Araxis Merge :

  달라진 부분을 보여주는 가이드라인이 너무 작아서 눈에 띄지 않음.

  단 선으로 바뀐 부분을 보여주기에 매우 많은 길이의 코드가 연속적으로 달라졋을 경우 직관적.

 

Beyond Compare :

  바뀐 부분을 영역색, 글씨색으로 나누어 보여주어서 보기 편함.

  달라진 부분을 보여주는 가이드라인의 길이가 화면크기와 별도로 나타나 직관적이지 않음.

  바뀐 부분이 한 줄의 일부, 아니면 몇줄 이하일 경우 직관적으로 보이나, 바뀐 부분의 길이가 길 경우, 특히 한페이지가 넘어 갈 경우는 보기가 상당히 불편하다.

 

Ultra Compare : 

  돈내고 쓸 가치가 없다. 알고리즘이 개판이다.


Kdiff

  한글 지원이 쓰레기 of 쓰레기라 배제


WinMerge

  제작자는 이 UI로 정말 코드 비교를 할수 있는지 한번 묻고싶다


[폴더비교]

Araxis Merge :

  폴더 비교 창이 매우 난잡하여 보기힘들다.

  필터가 매우 단순

  최신버전에서 필터 기능이 강력해졋다

Beyond Compare :

  알아보기 쉽게 색으로 잘 표시되어 있다.

  필터링 기능이 매우 막강하다. 특히 프로그래머가 jpg, bmp 파일을 Compare 툴로 보는것은 의미가 없는데 필터 옵션에서 아주 간단하게 걸러낼 수 있다.


[기타기능]

Araxis Merge:

  소스비교, 바이너리 비교. 그 이상의 잡기능은 없다

Beyond Compare:

  Mp3비교, 이미지 비교 등등 굉장히 다양한 포맷을 비교하는 기능을 제공한다.


[가격]

Araxis Merge :

  비싼 값에 비해, 밥값을 못한다.

  이제 밥값정돈 한다. 그래도 비싸다

Beyond Compare :

  유료이긴 하지만 비싸지 않고, 이 가격대에 이정도 툴이면 매우 훌륭하다.

 

KDiff, WinMerge : 

  싼게 비지떡이다. 정말 돈이 없다면 그때나 고민해 보자


 

PS. DiffMerge, AcroDiff 등 비교 예정

?

Lyn
조회 수 28273 추천 수 0 댓글 3
Atachment
첨부 '8'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

C++11 표준이 완성 되면서 상당히 많은 기능이 표준 라이브러리에 추가 되었습니다.

이들중 상당수는 완전히 새로운 클래스로 제공되는 것이 많지만 기존 기능을 보안하는 식으로 추가된것도 많습니다.

그중 가장 많이 쓰인다고 볼 수 있는 string 관련으로도 여러가지가 추가 되었습니다.


아래 코드는 최신의 Visual Studio 2012 에서 작성되었습니다.


첫번째로 Native언어 답게 메모리를 직접 관리 할 수 있는 함수가 추가 되었습니다.


1.png


원래 대부분의 stl 객체가 그렇든 한번 할당 한 메모리는 데이터 사이즈가 줄어든다 해도 줄이지 않았습니다.
하지만 C++11에서는 shrink_to_fit 매소드를 제공하여 메모리를 줄일 수 있도록 하고 있습니다.



2.png


그 다음으론 front, back, pop_back 함수의 추가입니다.
이름답게 front, back 은 각각 첫글자, 마지막 글자를 리턴하며 pop_back은 맨뒤에서 한글자를 잘라냅니다.



사실 이 다음부터가 가장 쓸만한 부분입니다.
C++의 string 은 숫자 관련 함수를 제공하지 않아 C의 atoi, itoa 처럼 배열을 기반으로 하는 함수를 사용하거나 stringstream 을 사용하여 문자열을 조립하는 과정을 필요로 하였습니다. C++11에서는 그것과 관련된 함수를 추가 하였습니다.


3.png


가장 기본적인 활용법입니다 stoi 함수는 문자열을 숫자로 변환합니다. type 에 따라 stoi, stol, stoll, stoul, stoull, stof, stod, stold로 바꿔쓸 수 있습니다.
각각 int, long, long long, unsigned long, unsigned long long, float, double, long double 로 변환하는 함수입니다.


4.png

뒤에 변환할 수 없는 문자열이 있을경우, 변환 가능한 부분 까지만 변환 후 몇글자가 변환되었는지 얻어올 수 있습니다.


5.png

진법 변환도 가능합니다.
16진수 100은 256으로 8진수 100은 64로 정상적으로 변환 되었습니다.

16진수 8진수만이 아니라 7진수 9진수 등 중간단계에 있는 진법으로도 정상적으로 변환이 가능합니다.


6.png


문자열을 언제나 숫자로 바꿀 수 있는것은 아니기 때문에 2 종류의 예외를 던질 가능성이 있습니다.
각각 숫자로 변환 불가능한 문자열과 너무 길어서 숫자의 범위를 넘어서는 문자열을 변환 시도 할 경우의 예외입니다.


7.png

기본적으로 0x를 앞에 붙일경우 0만 인식하여 0으로 변환 되지만 16진법으로 변화할 경우에 한정해서 0x를 인식하여 정상적인 문자열로 판단합니다.
8진법 변환의 경우 앞의 0 한자리만 인식하여 0으로 변환된것을 볼 수 있습니다.



지금까진 문자열을 숫자로 변환 하였지만 반대의 기능도 있습니다.


8.png


반대의 기능으로 to_string 함수를 제공합니다.
모든 정수/실수 타입에 대해 오버로딩 되어 있기때문에 단순히 호출만 하면 됩니다.


단 실수의 경우 무조건 소수점 7번째 자리에서 반올림하여 6자리로 표기하게 되어 있습니다.
자리수 조절이 필요 할 경우 format 기능이 있는 boost:format, stringstream, sprintf 등의 기존 함수를 사용하여야 합니다

?
  • ?
    노땅개발자 2012.09.25 01:15
    정리 참 잘해주셨네요.
    제 블로그에 출처 명시하고 퍼갑니다. ^^
  • ?
    최고의프로그래머 2012.09.26 01:35
    좋은 글 감사합니다. 출처명시하에 스크랩합니다
  • ?
    노력왕 2013.09.17 04:21
    와우 좋은 정보 입니다.
    제 블로그에도 퍼갈게요 좋은 하루 되세요 ^^

Lyn
조회 수 34462 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

역시 이번에도 아무도 관심가져주지 않는 (...) 불쌍한 주제를 하나 가지고 나와봤습니다


C++의 표준 라이브러리인 stl 의 특징이라고 하면 반복자(iterator)의 존재하고 할 수 있는데요...

이 반복자들은 여러가지 종류가 있습니다. 

정방향 or 역방향, 임의접근 or 순차접근, 상수 or 비상수 등 여러가지 조합의 반복자를 생성 할 수 있는데요 ...


이중 방향은 애초에 별도의 함수로 제공되고 (begin vs rbegin), 임의접근이냐 순차접근이냐는 컨테이너의 특성에 달린 문제었습니다.
그러나 상수 반복자(const_iterator)는 별도의 함수가 제공되지 않았는데요, C++특성상 비상수 -> 상수 의 변환은 자유롭기 때문입니다.

그래서 비상수 반복자를 리턴하는 begin 을 호출 후 상수반복자 type 의 변수에 대입하여 사용하는 식으로 구현 되었었지요.



하지만 C++11에선 상수반복자를 리턴하는 cbegin 이 추가되었습니다.
왜냐구요? auto 키워드의 존재 때문입니다. 

사용해보신 분은 아시겠지만 auto 는 한번 써보고 나면 없으면 stl 쓰기 싫어질 정도로 반복자와 함께 사용할때 아주 편한 기능인데, auto는 인터프리팅 언어들처럼 동적타입 변수가 아니라 우변의 type을 유추해서 컴파일타임에 type이 정해지기 때문에 begin 으로 리턴받은 반복자는 반드시 비상수 반복자가 됩니다.


그렇기에 C++11에서는 auto와 함께 사용할 수 있는 상수 반복자를 리턴하는 별도의 함수가 추가되었습니다. 애초에 상수반복자를 리턴하기 때문에 auto로 선언해도 좀 더 안전한 코드를 짤 수 있게 됩니다.


TAG •
?

Lyn
조회 수 4681 추천 수 0 댓글 1
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

C++ 은 C에서 유래한 오래된 언어 답게 가능한 한 최소한의 라이브러리만 가지고 있던 시절이 있었습니다. 

하지만 시대의 흐름은 거스를 수 없었고, STL이 추가 된 이후 200년대 이후 TR1을 시작으로 매우 많은 라이브러리들이 추가 되었습니다.

 

이 많은 라이브러리들은 모두 (당연하게도) 모두 C++로 만들어 져 있었으며 template 을 상당히 예전부터 가지고 있던 언어 답게 매우 많은 라이브러리가 template 기반으로 되어 있었고 template 의 특성상 라이브러리의 소스가 모두 공개될 수 밖에 없기 때문에 별다른 작업이 없이도 C++ 프로그래머들은 표준 라이브러리의 소스를 마음껏 볼 수 있었습니다(의외로 특정 언어의 라이브러리가 그 언어로 다 만들어진 경우가 드뭅니다)

 

덕분에 대체 tuple 의 소스는 어떻게 구현되어 있을까 궁금해서 열어봤다가, 2개부터 N개까지의 tuple 이 전부 따로 구현되어 있는 것을 보고 매우 실망했던 (T.T) 가슴아픈 기억도 있는데, C++ 표준위원회는 이러한 특정 라이브러리를 더 깔끔하게 만들기 위해 새 문법이 필요하다면 컴파일러 개발사들의 구현 가능여부 (....) 따위는 고려하지 않고 새 문법을 추가하였고(tuple 을 구현하기 위해 추가된 variadic template 라던가... 물론 이것도 고수들은 나름대로 다른곳에 쓸 방도를 찾아 내더군요. 그러라고 만들어준게 아닌 template 으로 metaprogramming을 한 것 처럼) 결국 영원히 추가되지 않을 듯 한 export 키워드라는 흑역사도 만들어 내었습니다.

 

하지만 C++11에서 Type Traits가 추가되면서 사정이 좀 달라지는데, 당시까지의 C++ 문법으로는 구현이 불가능한 함수들이 표준에 포함 되었기 때문입니다.

예를들어 std::is_integral<T> 는 해당 T type 이 정수형인가를 판정하는 함수인데, 이는 아주 단순하게 존재하는 모든 기본type 에 대해 해당 template 을 특수화 함으로서 해결하였습니다. 그 일부를 보면

 

01.png

 

대략 뭐 이런식이죠.

 

하지만 std::is_enum<T>, std::has_virtual_destructor<T> 등은 분명 라이브러리 형태로 제공 되어야 하나, 어떤 방법으로도 해당 정보를 프로그래머가 얻어낼 수 없습니다. 그렇다고 해당기능을 연산자로 넣기에는 너무 많은 연산자가 추가되어야 하고, 연산자 주제에 상당히 긴 이름을 가질 수 밖에 없는 문제가 있습니다. 물론 reinterpret_cast 같이 기존에도 이름이 긴 연산자가 있었으나, 이는 의도적으로 길게 만들어진 작명으로서 가능하면 쓰지 말라는 의미와 함께 만약 사용하였을 경우 눈에 잘 띄도록 하는 의미도 있습니다.

 

결국 언어에 문법을 추가되지 않았으나, 제공해야 하는 기능은 생겨 났고, 그 결과는 별 수 없이 컴파일러에 의해 코드가 자동 생성되도록 하는 대량의 컴파일러 확장키워드의 추가로 나타났습니다. 예를들어 VC++2015는 아래와 같은 매크로를 제공하는데, __(언더바 2개) 로 시작하는 함수는 전부 실제 존재하는것이 아닌 컴파일러가 컴파일 시점에 알아서 채워 주는 값들입니다.

 

// COMPILER SUPPORT MACROS

// VC++ V14 SUPPORT
  #define _IS_BASE_OF(_Base, _Der) \
: _Cat_base<__is_base_of(_Base, _Der)>
  #define _IS_CONVERTIBLE(_From, _To) \
: _Cat_base<__is_convertible_to(_From, _To)>
  #define _IS_UNION(_Ty) \
: _Cat_base<__is_union(_Ty)>
  #define _IS_CLASS(_Ty) \
: _Cat_base<__is_class(_Ty)>
  #define _IS_POD(_Ty) \
: _Cat_base<__is_pod(_Ty)>
  #define _IS_EMPTY(_Ty) \
: _Cat_base<__is_empty(_Ty)>
  #define _IS_POLYMORPHIC(_Ty) \
: _Cat_base<__is_polymorphic(_Ty)>
  #define _IS_ABSTRACT(_Ty) \
: _Cat_base<__is_abstract(_Ty)>
  #define _IS_FINAL(_Ty) \
: _Cat_base<__is_final(_Ty)>
  #define _IS_STANDARD_LAYOUT(_Ty) \
: _Cat_base<__is_standard_layout(_Ty)>
  #define _IS_TRIVIAL(_Ty) \
: _Cat_base<__is_trivial(_Ty)>
  #define _IS_TRIVIALLY_COPYABLE(_Ty) \
: _Cat_base<__is_trivially_copyable(_Ty)>
  #define _HAS_TRIVIAL_DESTRUCTOR(_Ty) \
: _Cat_base<__has_trivial_destructor(_Ty)>
  #define _HAS_VIRTUAL_DESTRUCTOR(_Ty) \
: _Cat_base<__has_virtual_destructor(_Ty)>
  #define _UNDERLYING_TYPE(_Ty) \
__underlying_type(_Ty)
  #define _IS_LITERAL_TYPE(_Ty) \
: _Cat_base<__is_literal_type(_Ty)>
  #define _IS_ENUM(_Ty) \
: _Cat_base<__is_enum(_Ty)>
  #define _IS_DESTRUCTIBLE(_Ty) \
: _Cat_base<__is_destructible(_Ty)>
  #define _IS_NOTHROW_ASSIGNABLE(_To, _From) \
: _Cat_base<__is_nothrow_assignable(_To, _From)>
  #define _IS_NOTHROW_DESTRUCTIBLE(_Ty) \
: _Cat_base<__is_nothrow_destructible(_Ty)>
  #define _IS_TRIVIALLY_ASSIGNABLE(_To, _From) \
: _Cat_base<__is_trivially_assignable(_To, _From)>
  #define _IS_CONSTRUCTIBLE \
__is_constructible
  #define _IS_NOTHROW_CONSTRUCTIBLE \
__is_nothrow_constructible
  #define _IS_TRIVIALLY_CONSTRUCTIBLE \
__is_trivially_constructible

 

 

전 이런 결과가 된 것이 언어가 제 컨트롤을 벗어난 것 같아 좀 아쉽기도 하고 한편으로는 라이브러리의 형태로 제공되느라 지저분해진 것들이 많은데(예를들면 std::map 이라거나 ... 요즘은 많은 언어들이 map 정도는 라이브러리가 아니라 문법차원에서 지원 하죠) 언어를 깔끔하게 만들기 위해선 좋다고 생각합니다. 

TAG •
?
  • ?
    사무엘 2016.01.01 03:46
    요즘 C++ 라이브러리는 반쯤은 언어를 확장해 가면서 제공되고 있군요. ㄷㄷㄷ
    reinterpret_cast는 일부러 가능한 한 쓰지 말라고 저렇게 길게 작명된 것이었고.. 좋은 정보 감사합니다!

Lyn
조회 수 32389 추천 수 0 댓글 4
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

C++의 STL 에서는 여러가지 알고리즘을 제공한다.
그중 "임의의" 동작을 할 수 있는 알고리즘들은 그 "동작" 의 대상이 되는 인자를 받도록 되어 있는데, 
그 "동작"의 조건은 ()연산자로 호출이 가능할것! 이다.


그 동작을 만족시키는것은 C에서는 함수가 있다.
또 C++에서는 STL 과 함께 소개된 함수객체(Functor)가 있으며, STL 초기부터 제공된 bind1st, bind2nd가 있고, boost에서 제공되는 mem_fn 도 있으며, 이 모든것을 통합한 범용 bind(C++11 or boost에 포함)도 존재한다.

그리고 최신의 C++11 표준에 포함된 lambda도 있고, boost의 lambda도 있지만, 이쪽은 C++11 표준에 lambda가 포함 된 이상 더이상 쓸 일은 없을테니 이번 실험에선 제외한다.


실험순서는 전역함수, bind된 전역함수, 함수객체, 람다, bind된 람다, auto를 이용해 bind된 람다 의 순이다.

실험은 Visual C++ 2010 Sp1, x86 Debug Build에서 테스트 하엿다. Release Mode 도 특성은 동일하다.

궂이 Debug Build로 테스트 한 이유는 Release모드에서 자꾸 전역함수를 inline화 시키는 바람에 =_=;


코드 나간다.


#include <cstdlib>
#include <cstdio>
#include <vector>
#include <random>
#include <cstdint>
#include <algorithm>
#include <functional>
#include <windows.h>
 
using namespace std;
 
__int64 g_NumberSum;
 
void GetSumFunction(int Num)
{
	g_NumberSum = g_NumberSum + Num;
}
 
struct GetSumFunctor
{
	void operator()(int Num)
	{
		g_NumberSum = g_NumberSum + Num;
	}
};
 
void wmain()
{
	const int NUMBER_COUNT = 100000000;
 
	mt19937_64 RandomEngine;
	uniform_int <> RandomRange(0, INT32_MAX);
	RandomEngine.seed(GetTickCount());
 
	vector<int> RandumNumbers;
	RandumNumbers.reserve(NUMBER_COUNT);
	for (int i = 0; i < NUMBER_COUNT; ++i)
	{
		RandumNumbers.push_back(RandomRange(RandomEngine));
	}
 
	DWORD Tick;
//function
	g_NumberSum = 0;
	Tick = GetTickCount();
	for_each(RandumNumbers.begin(), RandumNumbers.end(), GetSumFunction);
	printf("Global Function :: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick);
//bind function
	g_NumberSum = 0;
	function<void(int)> FunctionObject = bind(&GetSumFunction, tr1::placeholders::_1);
	Tick = GetTickCount();
	for_each(RandumNumbers.begin(), RandumNumbers.end(), FunctionObject);
	printf("Bind Function   :: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick);
//functor
	g_NumberSum = 0;
	Tick = GetTickCount();	
	for_each(RandumNumbers.begin(), RandumNumbers.end(), GetSumFunctor());
	printf("Functor         :: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick);
//C++ 11 Lambda
	g_NumberSum = 0;
	Tick = GetTickCount();
	for_each(RandumNumbers.begin(), RandumNumbers.end(), 
		[](int Num)
		{
			g_NumberSum = g_NumberSum + Num;
		});
	printf("C++11 Lambda    :: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick);
//C++11 Bind Lambda
	g_NumberSum = 0;
	Tick = GetTickCount();
	function<void(int)> BindLambda = 
		[](int Num)
		{
			g_NumberSum = g_NumberSum + Num;
		};
	for_each(RandumNumbers.begin(), RandumNumbers.end(), BindLambda);
	printf("Bind Lambda     :: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick);
//C++11 Auto bind Lambda
	g_NumberSum = 0;
	Tick = GetTickCount();
	auto AutoBindLambda = 
		[](int Num)
		{
			g_NumberSum = g_NumberSum + Num;
		};
	for_each(RandumNumbers.begin(), RandumNumbers.end(), AutoBindLambda);
	printf("Auto Bind Lambda:: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick); 
} 



아래는 결과이다.

lambda.png


결과를 보면 lambda 가 가장 빠른 것을 볼 수 있다. 길게 나불대지 않고 성능 이슈와 원인을 아래 간략히 적어본다.
1. 전역함수의 경우 함수 Call 오버헤드에 의해 속도가 조금 감소하엿다.

2. lambda, functor 는 사실상 오차범위 내의 차이라고 보인다.

3. bind lambda 의 경우는 std::fuction 객체가 함수호출 정보를 RTTI에 의존하는 특징때문에 속도를 왕창 까먹게 된다.

4. bind 된 전역함수의 경우는 RTTI의 오버헤드 + 함수호출로 인해 가장 느려진다.

5. auto를 사용해 변수에 저장한 lambda 는 std::fuction객체에 저장 하는 것이 아니라 일종의 inline 함수처럼 구현해준다. 그래서 오버헤드가 전혀 없이 빠른 속도를 보여준다. 즉 같은 함수객체를 2번이상 이용 할 경우 코드를 Copy&Paste 하지 않아도 auto를 이용하면 성능과 중복방지 두마리 코드를 다 잡을 수 있다.

?
  • ?
    elrha 2012.08.16 18:27

    으아 이거 좋은정보네요


    테스트는 안해봤지만 auto 객체 마우스 오버해보면 std::function으로 나올듯 한데..


    결국 컴파일러 지능테스트인건가요 ㅋㅋㅋㅋ

  • profile
    Lyn 2012.08.17 07:23

    아뇨 함수포인터 취급해요 ㅎㅎ


    컴파일 타임에 완전한 호출 정보를 알고있는 상황에서 궂이 오버헤드가 있는 std::function으로 컴파일할 이유가 없죠

  • ?
    11ho 2014.03.25 05:22
    감사합니다. 속이 다 후련하네요 ㅠㅠ
  • ?
    해피 2015.07.17 18:45
    퍼가용

Atachment
첨부 '3'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

C++ 템플릿 상속엔 골 때리는 문제가 있는데 ...

바로 베이스클래스의 멤버에 접근하려면 베이스 클래스의 이름을 명시해야 한다는 것이다... 안그러면 이름을 못찾아온다

사람 상당히 귀찮게 만드는놈이라 할 수 있겠다.

보통 일반적으론 볼일이 없고 Mixin 을 이용하거나 아니면 Effective C++ 을 읽으면서 알게된다(책에는 "못찾는다" 라고 되어 있다)


간단히 말하면 이런 코드다

#include <cstdio>

void foo()
{
	printf("Global Function\n");
}
template <typename T>
class Cls1
{
	T Var1;
public:
	void foo()
	{
		printf("Member Function\n");
	}
};

template <typename T>
class Cls2 : public Cls1<T>
{
	T Var2;
public:
	void test()
	{
		Cls1<T>::foo();
	}
};

int main()
{
	Cls2<int> cls2;
	cls2.test();

	return 0;
}


근데 만약 명시 하지 않으면 어떻게 될까?


일단 최신의 VC++ 2012에서 돌려보자

01.png


헐...? 정확히 멤버 함수를 찾아온다. 여기엔 올리지 않겠지만 VS2005~2010 도 모두 같은 동작을 한다.

다른컴파일러에서 해보자. gcc 4.4다.


02.png


헐?! 글로벌 함수를 찾는다 (...) 이거뭥미.


그럼 최신의 C++0x를 지원하는 gcc4.7에서 해보자.


03.png


역시 전역함수를 찾는다.


표준문서는 귀찮아서 (...) 확인하지 않았지만 관련 서적 등을 보면 gcc의 동작이 맞는 것으로 보인다.
하지만 저런 코드를 짜면서 gcc 쪽 동작을 원하는 사람이 과연 있을까... 하는 생각이 든다. 일반적인 클래스를 만드는 느낌으로 당연히 멤버함수가 호출 될 것이라고 생각 하지 않을까? 이 결과를 확인하면서 C++은 당최 생각대로 움직여 주지 않는 매저키스트 들을 위한 언어란 누군가의 말이 귓가에 맴돈다 (...)


결론 : EC++에 나온대로 그냥 제대로 포커스 지정 하자 (...) 야!


PS. gcc 에서는 저렇게 두가지 모두 있는 경우가 아니라 전역 foo 함수가 없는 (즉 이름을 찾을 수 없는) 경우에는 당연히 이름을 찾지 못해 에러를 내는데, 이 경우 컴파일 옵션에 -fpermissive 를 추가 하는 것으로 멤버함수로의 연결이 가능하다(워닝은 뜬다)
단 전역 foo 함수가 존재 할 경우 저 옵션을 그냥 무시하고 그냥 전역 함수로 연결해 버린다.


PS2. 혹시 LLVM-clang 을 사용할 수 있는 환경에 계신분은 어떤 결과가 나오는지 알려주시면 좋겠다.



?
  • ?
    123 2012.09.03 03:48
    VS 에서는 자동으로 찾아주네요.. 역시 상용이라 틀린가보네요..
    clang 으로 컴파일 해서 실행해보니 gcc 하고 같네요. .
    관련글에는 이렇게 나오네요
    While non-dependent names are resolved "normally" – when the template is defined,
    the resolution for dependent names happens at the point of the template’s instantiation.
    그러까 템플릿 인스턴스시 resolve 가 되게할려면 dependent name 으로 만들어 줘야 되네요
    Cls1<T>::foo() or this->foo() 이런식으로..

    http://eli.thegreenplace.net/2012/02/06/dependent-name-lookup-for-c-templates/

Board Pagination Prev 1 ... 2 3 4 5 6 7 ... 8 Next
/ 8