help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Oct-file error message construction and octave_value conversions


From: Andrew Janke
Subject: Re: Oct-file error message construction and octave_value conversions
Date: Wed, 30 Jan 2019 17:39:26 -0500
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:60.0) Gecko/20100101 Thunderbird/60.4.0


On 1/30/19 5:41 AM, Kai Torben Ohlhus wrote:
> 
> 
> On Wed, Jan 30, 2019 at 1:40 AM Andrew Janke <address@hidden
> <mailto:address@hidden>> wrote:
> 
>     Hi, folks,
> 
>     Thanks for bearing with me and all my questions on oct-files in IRC.
> 
>     I'm trying to construct detailed error messages for some of my oct
>     functions that incorporate size, type, and value info about their
>     inputs, but having a hard time doing so. Here's what I'm trying:
> 
>     #include <cmath> #include <iostream> #include <octave/oct.h>
>     DEFUN_DLD (s01_02_error_msg_string_construction, args, nargout,
>                 "Error message construction using argument type")
>     {
>        octave_value x = args(0);
> 
>        std::string x_type_name = x.type_name ();
>        std::string msg =std::string ("Type of arg 1 is: ")+ x_type_name;
>        error (msg.c_str ());
> 
>        builtin_type_t x_type = x.builtin_type ();
>        std::string msg2 =std::string ("Builtin type id of arg 1 is: ")+
>     x_type;
>        error (msg2.c_str ());
> 
>        octave_idx_type n_elems = x.numel ();
>        std::string msg3 =std::string ("Numel in arg 1: ")+ n_elems;
>        error (msg3.c_str ());
>     }
> 
> 
>     The first "msg = ..." statement works. But each of those
>     other "msgX = ..." lines is giving me a compiler error. It's complaining
>     that "no viable conversion from 'octave_value' to 'std::string'".
>     Which is weird,
>     because builtin_type_t and octave_idx_type are not octave_values,
>     are they?
>     builtin_type_t is an enum, and octave_idx_type is a typedef to an
>     integer type.
>     Why does the compiler think an octave_value is involved here?
> 
>     (BTW, yes, I know I should be using type_name() and not
>     builtin_type(); I'm just
>     including it here to help track down the conversion issue I'm not
>     understanding.)
> 
>     I'd like to stick with constructing std::string messages instead of
>     using the printf style
>     controls that error accepts (like 'error ("Numel in arg 1: %ld",
>     (long) octave_idx_type)')
>     because I want to use these with generic templated functions that
>     will use the template
>     types in the error message construction; "std::string + x" is
>     polymorphic, but printf
>     placeholders are not.
> 
>     Cheers,
>     Andrew
> 
> 
> 
> 
> 
> Hi Andrew,
> 
> Somehow I got interested in your problem and hope to present a
> satisfactory answer found by try&error and [1,2] to both of us.
> The problem is best explained with the following program:
> 
> ====== CODE START ========
> // Compile with: g++ -std=c++11 -I/path/to/octave -pedantic -Wall
> -Wextra -o test.exe test.cc
> 
> #include <iostream>
> // #include <octave/oct.h>
> 
> int main () {
>   int x_type_name = 12;
>   // Without <octave/oct.h>
>   // error: no match for ‘operator+’ (operand types are
>   //   ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ and
> ‘int’)
> 
>   // With <octave/oct.h>
>   // error: conversion from ‘octave_value’ to non-scalar type
>   //   ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’
> requested
>   std::string msg = std::string ("Type of arg 1 is: ") + x_type_name;
>   return 0;
>
> ====== CODE END ========
> 
> As you can see, the root problem is that there is nothing like
> 
>    std::string::operator+(int);
> 
> Now g++ is desperate, but not beaten yet: It tries to find a matching
> operator even harder.
> My guess is when oct.h is included you get a bunch of new operators:
> 
> a) there is an operator  octave_value::operator+(octave_value)
> b) there are constructors octave_value(std::string) and octave_value(int)
> c) g++ tries to make use of it, as there is nothing better suited
> ==> PROBLEM: there is nothing like  std::string(octave_value)  for
> implicit back conversion. And that is the error message in this case.
> 
> Bottomline, this is not Octaves fault try to use "std::to_string" [3] to
> help g++ with its operator finding, i.e.
> 
>    std::string msg3 =std::string ("Numel in arg 1: ") + std::to_string
> (n_elems);
> 
> and you can go on.
> 
> Best,
> Kai
> 
> [1] https://en.cppreference.com/w/cpp/language/overload_resolution
> [2] https://en.cppreference.com/w/cpp/language/adl
> [3] https://en.cppreference.com/w/cpp/string/basic_string/to_string
Wow. C++, man.

I switched to your explicit-conversion approach and my code is happy
now. Thanks!

Cheers,
Andrew



reply via email to

[Prev in Thread] Current Thread [Next in Thread]